C++动态库对外导出函数的⽅法
1 windows的动态库
两种⽅法:
(1) ⼀种⽅式是采⽤模块定义(.def) ⽂件声明,.def⽂件为链接器提供了有关被链接程序的导出、属性及其他⽅⾯的信息。
(2) ⽤__declspec(dllexport)来声明函数,declspec是declare specifier的缩写,即声明某种说明符。
加extern "C"时:
extern "C"
{
__declspec(dllexport) RETURN_TYPE FUNCTION()
{
}
}
这是由于在制作DLL导出函数时由于C++存在函数重载,因此__declspec(dllexport) FUNCTION(int,int) 在DLL会被decorate,例如被decorate成为 function_int_int,⽽且不同的编译器decorate的⽅法不同,造成了在⽤GetProcAddress取得FUNCTION地址时的不便,使⽤extern "C"时,上述的decorate不会发⽣,因为C没有函数重载,如此⼀来被extern"C"修饰的函数,就不具备重载能⼒。
查看导出函数列表:
使⽤dumpbin /exports 动态库
例如:dumpbin /exports “C:\Windows\System32\ur32.dll”
2 linux的动态库
⽅法
在linux中,使⽤gcc进⾏脚本编译,默认情况下,会将⾮static的⽅法以及类都导出到so中
这种特性让我们⽅便使⽤时,有时候也会出现导出库的重名以及冲突。
linux的动态库加载库时,如果存在的就会进⾏覆盖,最终形成⼀套函数表,这就有可能会产⽣部分导出函数冲突,调⽤后崩溃的现象。
为了解决这种问题,必须对导出的函数进⾏规划,让⼀部分函数变为内部符号,不进⾏导出。
要做到这⼀点,需要做两件事:
1、对导出的符号进⾏定义,显⽰进⾏导出
__attribute__((visibility ("default"))) void add(int a, int b)
使⽤__attribute__((visibility ("default")))来说明,这个函数需要导出的
2、对makefile进⾏修改,设置默认的函数均为local
%.o:%.cpp
$(CXX) -fvisibility=hidden -g -fPIC ${INCLUDE} -o $@ -c $<
在使⽤动态库函数时,可加上extern变量表⽰使⽤的函数时外部定义的
查看导出函数列表:使⽤nm⼯具 nm -D 动态库例如: nm -D mylib.so