首先说明linux下生成静态链接库
libxxx.a
和动态链接库libxxx.so
假设现在有func.h以及其中函数的实现文件func.cpp
静态库.a :
ar -rcs libfunc.a func.cpp
动态库.so :g++ -fpic -shared func.cpp -o libfunc.so
gcc和g++会优先搜索.so,其次寻找.a
为了解释extern "C"
需要用到工具反汇编工具objdump
, 使用objdump -t *
查看符号表
utils.h
int func(int, int);
utils.cpp
#include "utils.h"
int func(int a, int b){
return a + b;
}
main.cpp
#include <iostream>
#inlcude "utils.h"
int main(){
std::cout << func(12, 12) <<< std::endl;
return 0;
}
使用g++编译
g++ -c utils.cpp -o utils.o
生成utils.o;再使用objdump查看符号表
可以看出int func(int, int)
函数的符号表为_Z4funcii
:其中_Z
为前缀,4
表示函数名有几个字符,后面紧跟函数名func
;之后的ii
为参数类型。由此可以看出c++通过此种方式支持函数重载,并且符号表中并没有对返回值类型进行体现,由此可以得出int func(int, int)
和函数void func(int, int)
不能构成函数重载。
接下来看看如果使用extern "C"
标记,产生的符号表
修改utils.h
文件
#ifdef __cplusplus
extern "C" {
#endif
int func(int, int);
#ifdef __cplusplus
}
#endif
使用命令g++ -c utils.cpp
生成utils.o
文件,并使用objdump
查看符号表
由上可知为什么c语言不支持函数重载,因为在函数的符号表中没有什么用来区分重载函数,而c++可以。
并且,最终对main.cpp
进行编译,查看符号表可知,其实main函数是按c语言形式生成符号表,因为目的是为了避免重载。
通常在使用静态和动态链接库时需要使用extern "C"