目录
1 背景
2 示例
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语言的方式编译。
×


