Linux 共享库中函数的可见性
Linux 共享库中函数的可见性
Linux共享库中的函数,默认都是可以外部可见的,也就是不需要像Windows下通过DEF文件或者dllexport指令来导出。先写一个源文件:MyExportFunctions.cpp
,内容如下:
1 |
int Add(int a, int b) { |
用gcc编译成共享库:
1
|
gcc -shared -o libExportFunctions.so MyExportFunctions.cpp
|
用nm -g
命令看查看所有导出的函数,Add和Sub都已经导出了。
1 |
nm -g libExportFunctions.so |
不过为什么函数名不是Add和Sub,而是_Z3Addii和_Z3Subii (可以给nm 加上参数 –demangle来把c++修饰后的名字翻译回来,也可以用c++filt这个命令来转换),这是因为这两个函数是在c++源文件里声明的,而c++编译器会给函数名自动加上一些修饰符,解决方法就是加extern “C”.
1 |
extern "C"{ |
nm -g 的结果是这样
1 |
nm -g libExportFunctions.so |
这样Add和Sub都是原来的名字了。
那怎么样只导出需要的函数呢?gcc的一篇关于可见性的wiki说得挺详细gcc函数可见性
先在编译时用-fvisibility=hidden把函数都改成默认不可见 ,然后在需要导出函数的声明前加attribute ((visibility (“default”)))。修改后的代码
1 |
extern "C"{ |
然后在编译时加上-fvisibility=hidden
1
|
gcc -shared -fvisibility=hidden -o libExportFunctions.so MyExportFunctions.cpp
|
这次nm -g的输出中就只有Add,没有Sub了
1 |
nm -g libExportFunctions.so |
上面说的这种方式类似Windows下的dllexport指令,那有没有跟DEF文件类似的东西可以在配置文件里配置哪些函数是导出的呢?gcc也有类似的配置文件,可以看GNU Export Maps。用法很简单,创建一个文本文件,叫exportmap,内容是这样
1 |
{ |
然后编译时带–version-script参数
1
|
gcc -shared -Wl,--version-script=exportmap -o libExportFunctions.so MyExportFunctions.cpp
|
用nm -g
查看,结果是
1 |
nm -g libExportFunctions.so |
评论暂时关闭