c++中,调用c语言函数时要对函数添加声明extern "C",这是因为c和c++的符号表机制不一样导致的。

假设存在函数fun,经过gcc编译后,该函数在符号表中的名字是fun,但是经过g++编译后,该函数在符号表中的结果是xxfunxx,c++编译器会在函数两侧加上一些随机字符。因为两者的编译结果不统一,所以混合使用的时候程序找不到符号,无法运行(甚至都无法编译)。一个典型的错误就是(参考实际开发中出现的一个案例:一次undefined reference to *的编译错记录):

/tmp/cccZeFer.o: In function `main':
main.cpp:(.text+0xf): undefined reference to `add'
collect2: error: ld returned 1 exit status

extern "C"语句的作用就是告诉c++编译器:我这个是c语言函数,不要按照你的格式来修改这个函数的符号,按照我的标准来就行了。于是c++编译器编译的时候就按照c的规范来,把两者符号统一。

示例

#include<stdio.h>

int add(int i, int j) {
    return i + j;
} 

int main() {
    printf("%d\n", add(1, 2));
    return 0;
}

代码中有一个函数add,看看它经过gcc和g++编译后分别变成了什么。

使用gcc编译:

image.png

使用g++编译:

imagedb520d0468aeb499.png

两者对比,很明显能看到,使用g++编译后的add函数,符号表前后加上了一些特殊字符。而gcc编译出来的符号就是add本身。

给add函数加上extern "C"声明后:

#ifdef __cplusplus
extern "C" {
#endif

int add(int i, int j) {
    return i + j;
} 

#ifdef __cplusplus
}
#endif

再次使用g++编译,add的符号就和gcc编译出来的符号一样了:

image416e247cd34d6a8f.png

最后修改:2019 年 09 月 15 日
如果觉得我的文章对你有用,请随意赞赏