目录
1 背景
C语言和C++语言是项目开发中经常用到的语言,在开发过程中经常会遇到C++程序要调用C程序的场景。如果项目代码是C语言写的,而使用的代码测试框架是C++写的,为了测试C项目代码,自然而然就会在C++代码中调用C代码写的函数。
在C++代码调用C代码写的函数过程中,遇到的最大问题就是找不到符号,具体原因是因为C语言和C++语言在生成函数符号是有差异的。
2 示例
比如在foo.c的文件中代码如下:
int foo(int x, int y) {
return x + y;
}
foo.h的代码如下:
int foo(int x, int y);
使用gcc工具编译生成foo.o文件
parallels@ubuntu-linux-20-04-desktop:~/leecode2/ar$ gcc -c foo.c
parallels@ubuntu-linux-20-04-desktop:~/leecode2/ar$ ll
total 20
drwxrwxr-x 2 parallels parallels 4096 May 16 19:49 ./
drwxrwxr-x 13 parallels parallels 4096 May 16 19:45 ../
-rw-rw-r-- 1 parallels parallels 44 May 16 19:46 foo.c
-rw-rw-r-- 1 parallels parallels 22 May 16 19:47 foo.h
-rw-rw-r-- 1 parallels parallels 1296 May 16 19:49 foo.o
然后使用ar工具生成静态库
parallels@ubuntu-linux-20-04-desktop:~/leecode2/ar$ ar -crv libfoo.a foo.o
a - foo.o
parallels@ubuntu-linux-20-04-desktop:~/leecode2/ar$ ll
total 24
drwxrwxr-x 2 parallels parallels 4096 May 16 19:51 ./
drwxrwxr-x 13 parallels parallels 4096 May 16 19:45 ../
-rw-rw-r-- 1 parallels parallels 44 May 16 19:46 foo.c
-rw-rw-r-- 1 parallels parallels 22 May 16 19:47 foo.h
-rw-rw-r-- 1 parallels parallels 1296 May 16 19:49 foo.o
-rw-rw-r-- 1 parallels parallels 1436 May 16 19:51 libfoo.a
编写test.cpp文件
#include "foo.h"
int main() {
int ret = foo(10, 20);
return 0;
}
使用gcc工具进行静态链接,此时出现了undefined符号的问题。
parallels@ubuntu-linux-20-04-desktop:~/leecode2/ar$ gcc test.cpp -L. -lfoo -o test
/usr/bin/ld: /tmp/cc96XOXw.o: in function `main':
test.cpp:(.text+0x10): undefined reference to `foo(int, int)'
collect2: error: ld returned 1 exit status
解决方法,包含头文件时使用extern "C",修改test.cpp文件如下:
extern "C" {
#include "foo.h"
}
int main() {
int ret = foo(10, 20);
return 0;
}
再使用gcc工具进行链接就成功了,因为extern "C"告诉编译器使用C语言的方式进行编译,这样就可以解决符号未定义的问题了。
parallels@ubuntu-linux-20-04-desktop:~/leecode2/ar$ gcc test.cpp -L. -lfoo -o test
parallels@ubuntu-linux-20-04-desktop:~/leecode2/ar$ ll
total 40
drwxrwxr-x 2 parallels parallels 4096 May 16 19:54 ./
drwxrwxr-x 13 parallels parallels 4096 May 16 19:45 ../
-rw-rw-r-- 1 parallels parallels 44 May 16 19:46 foo.c
-rw-rw-r-- 1 parallels parallels 22 May 16 19:47 foo.h
-rw-rw-r-- 1 parallels parallels 1296 May 16 19:49 foo.o
-rw-rw-r-- 1 parallels parallels 1436 May 16 19:51 libfoo.a
-rwxrwxr-x 1 parallels parallels 9280 May 16 19:54 test*
-rw-rw-r-- 1 parallels parallels 93 May 16 19:54 test.cpp
当然我们也可以修改foo.h头文件,将该头文件修改为:
#ifndef _FOO_H_
#define _FOO_H_
#ifdef _cplusplus
extern "C" {
#endif
int foo(int x, int y);
#ifdef _cplusplus
}
#endif
#endif
使用以下命令进行编译。
parallels@ubuntu-linux-20-04-desktop:~/leecode2/ar$ gcc test.cpp -L. -lfoo -D _cplusplus -o test
parallels@ubuntu-linux-20-04-desktop:~/leecode2/ar$ ll
total 40
drwxrwxr-x 2 parallels parallels 4096 May 16 21:39 ./
drwxrwxr-x 13 parallels parallels 4096 May 16 19:45 ../
-rw-rw-r-- 1 parallels parallels 44 May 16 19:46 foo.c
-rw-rw-r-- 1 parallels parallels 130 May 16 21:32 foo.h
-rw-rw-r-- 1 parallels parallels 1296 May 16 19:49 foo.o
-rw-rw-r-- 1 parallels parallels 1436 May 16 19:51 libfoo.a
-rwxrwxr-x 1 parallels parallels 9280 May 16 21:39 test*
-rw-rw-r-- 1 parallels parallels 74 May 16 21:32 test.cpp
parallels@ubuntu-linux-20-04-desktop:~/leecode2/ar$
3 C语言程序调用C++代码库
反过来C语言程序怎么调用C++代码库呢?实际上需要为C++代码库增加一个中间层,这个中间层为了给C++代码库向外提供一组C代码使用的接口,这些接口需要使用C语言的方式编译。
×
178

被折叠的 条评论
为什么被折叠?



