原标题:你真的知道C语言里extern "C" 的作用吗?
经常在C语言的头文件中看到下面的代码:
# ifdef__cplusplus
extern"C"{
# endif
// all of your legacy C code here
# ifdef__cplusplus
}
# endif
这通常用于 C++ 和 C 混合编程的时候,为了防止 C++ 的编译器在编译 C 文件的时候出现错误;
众所周知, C++ 可以进行函数名重载,但是 C 则没有这种功能,那这和 extern "C" 又有什么关系呢?
先看下面这个表格,如下所示;
语言
描述
C
函数名可以作为 唯一ID和 代码段的程序建立联系
C++
因为重载的关系,函数名符号会被破坏,从而会根据 函数的参数不同而重新生成函数符号
未添加 extern "C"
test.h
# ifndefTEST_H
# defineTEST_H
voidfoo1( void);
voidfoo2( void);
voidfoo3( inti);
# endif
test.c
voidfoo1( void){}
voidfoo2( void){}
voidfoo3( inti){}
intmain( intargc, char** argv){
foo1;
foo2;
foo3( 1);
return0;
}
编译这两个文件,生成 test.o 文件,通过 objdump 查看函数符号;
g++ -c test.c test.h
objdump -t test.o
可以看到函数符号已经被编译器修改了;
添加extern "C"
test.h
# ifndefTEST_H
# defineTEST_H
# ifdef__cplusplus
extern"C"{
# endif
voidfoo1( void);
voidfoo2( void);
voidfoo3( inti);
# ifdef__cplusplus
}
# endif
# endif
test.c
# ifdef__cplusplus
extern"C"{
# endif
voidfoo1( void){}
voidfoo2( void){}
voidfoo3( inti){}
# ifdef__cplusplus
}
# endif
intmain( intargc, char** argv){
foo1;
foo2;
foo3( 1);
return0;
}
编译这两个文件,生成 test.o 文件,通过 objdump 查看函数符号;
g++ -c test.c test.h
objdump -t test.o
这时候函数符号是正确的;
extern "C" 是告诉 C++ 的编译器不要打我这些C函数的主意。
来源:公众号小麦大叔返回搜狐,查看更多
责任编辑: