3. extern "C" 声明
C++ 语言的函数(main函数除外)在编译阶段都会被改成编译器能够识别的函数别名,这个函数别名只有生成此目标文件的编译器才能够识别,并且各种编译器为函数取的别名也各不相同。也就是说 C++ 编译出来的目标文件无法交给 C 语言的编译器来链接成为可执行文件。即 C 语言无法调用 C++ 语言编写的程序。解决这个问题的语法是 extern "C" 声明。
extern "C" 声明是 C++ 独有的声明(C语言不支持此声明),他的作用是告诉编译器,使用 extern "C" 声明的一个或多个函数的名称使用原始的 C 语言的标准名称,不添加前缀和后缀,以便于 C 语言 的程序调用(用来实现 C 和 C++ 语言的混合编程)。
语法有如下两种
声明一个函数的语法:
extern "C" 一个函数的声明
同时声明多个函数的语法:
extern "C" {
函数的声明1;
函数的声明2;
...
函数的声明n;
}
示例:
// filename: extern_c.cpp
#include <iostream>
using namespace std;
// 声明 myadd 为 C 语言函数
extern "C" int myadd(int a, int b);
// 声明 mymul 为 C 语言函数
extern "C" {
float mymul(float x, float y, float z);
}
int myadd(int a, int b) {
return a + b;
}
float mymul(float x, float y, float z) {
return x * y * z;
}
int main(int argc, char * argv[]) {
cout << myadd(1, 2) << endl;
cout << mymul(3.4, 5.6, 7.8) << endl;
return 0;
}
链接结果和编译运行如下所示:
weimz@mzstudio:~$ gcc -o extern_c.o -c extern_c.cpp
weimz@mzstudio:~$ nm extern_c.o
U _GLOBAL_OFFSET_TABLE_
0000000000000040 T main
0000000000000000 T myadd
0000000000000018 T mymul
U _ZNSolsEf
U _ZNSolsEi
U _ZNSolsEPFRSoS_E
U _ZSt21ios_base_library_initv
U _ZSt4cout
U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
weimz@mzstudio:~$ g++ -o extern_c extern_c.o
weimz@mzstudio:~$ ./extern_c
3
148.512
可见 myadd 和 mymul 两个函数都编译成了 C 语言的标准函数。