目录
一、extern "C" 的作用
extern "C" {
int foo(int x, int y);
}
C 函数按 C 风格编译时,函数 foo 在编译后的符号库中的符号大概是 _foo,只包括函数名。
C++ 直接包含 C 的头文件编译,是 C++ 风格编译,foo 在编译时的符号库中的符号大概是 _fooii,包含函数名、参数类型。这时 C++ 中调用点调用 foo 函数会去 C 编译文件中找 _fooii 符号,但是因为 C 库编译时生成的是 _foo 符号,因此无法找到一个匹配的符号,编译错误。
C++ 用 extern "C" 包含 C 的头文件编译后,该部分文件按照 C 的风格进行编译,foo 在编译时的符号库中的符号大概是 _foo,包含函数名。这时 C++ 中调用点调用 foo 函数会去 C 编译文件中找 _foo 符号,因为 C 库编译时生成的是 _foo 符号,因此可以找到一个匹配的符号。
C++ 为了支持重载,编译函数时生成的符号包括:函数名、函数参数,导致同一函数在 C++ 中的符号(是按C++编译的)与 在 C 中的符号(是按C编译的)不匹配,这造成了 C++ 不能直接调用 C 函数。extern "C" 解决了这一问题。
二、测试程序
/* cExample.h */
#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
int add(int x, int y);
#endif
/* cExample.c */
#include "cExample.h"
int add(int x, int y) // _add
{
return x + y;
}
/* test.cc */
#include <iostream>
extern "C" {
#include "cExample.h" // _add_ii ---> _add
}
int add(double a, int b); // _add_di
using namespace std;
int main(){
cout << add(2,3) << endl;
return 0;
}
int add(double a, int b){
return a+b;
}
gcc -c cExample.c -o cExample.o
g++ test.cc cExample.o -o test
./test