被extern "C"修饰的变量和函数是按照C语言方式进行编译和链接的
举个例子:
1.moduleA、moduleB两个模块
2.B调用A中的代码
3.其中A是用C语言实现的,而B是利用C++实现的
//moduleA头文件:moduleA.h
#ifndef __MODULE_A_H
#define __MODULE_A_H
int fun(int, int);
#endif
//moduleA实现文件:moduleA.c
#include"moduleA"
int fun(int a, int b)
{
return a+b;
}
//moduleB头文件:moduleB.h
#idndef __MODULE_B_H
#define __MODULE_B_H
#ifdef __cplusplus //而这一部分就是告诉编译器,如果定义了__cplusplus(即如果是cpp文件, extern "C"{ //因为cpp文件默认定义了该宏),则采用C语言方式进行编译
#include"moduleA.h"
#endif
… //其他代码
#ifdef __cplusplus
}
#endif
#endif
//moduleB实现文件:moduleB.cpp
#include"moduleB.h"
int main()
{
cout<<fun(2,3)<<endl;
}
解释:
1.moduleA实现文件是用C实现的,所以函数编译出来的符号是不带形参类型的(因为C语言没有重载,所以编译出来符号只需要函数名唯一标识),如_fun
2.moduleB实现文件是用CPP实现的,它中间使用了fun函数,默认情况下,int fun(int, int);编译成了_fun_int_int这样的符号,这个时候链接到目标文件,就会找不到符号而报错
3.如果让int fun(int, int);在moduleB实现文件中也编译成_fun这样的符号,就可以正常工作了。所以就需要在这个函数声明的地方,用extern “C"标记,所以在moduleB的的头文件中用extern ”C"标识
总结:
1. c文件的源码编译出来的函数符号是不带形参的
2. c++中可能会链接到c源码编译出来的目标文件,这个时候需要C++中包含C函数声明的时候用extern "C”指定,这样C++源码编译出来的C函数的符号也是按照C的规则,不带形参的
这样最终目标模块链接的时候,符号就能对应上
3.总之,如果一个C++源文件中要使用一个用C代码实现的函数,那么C++文件应该使用extern "C"对这个函数进行声明,保持链接的时候符号兼容
参考链接:https://blog.csdn.net/jiqiren007/article/details/5933599