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\user32.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