两者的区别
在c++的符号表中,一个符号有两个属性,分别是Bind和Vis,Bind主要分为三类:
- global
- local
- weak
- unique
这里先不讨论最后两个,主要看global和local,我们知道global代表这个符号在链接的时候可以被其他object看到,local的话则告诉链接器不要打我注意,不能被其他编译单元看到。在C++里面一个函数或者全局变量一旦加了static,那么该函数和变量只能在这一个编译单元使用。
再来看Vis,主要分为三类: - default
- hidden
- protect
这里也主要分析前两个,default代表这个动态库
的该字符能被其他项目引用,而hidden
则表示,该动态库的该字符无法被其他项目引用,这里要注意指的是动态库被链接的时候,而在生成动态库或者可执行文件时候(换句话说就是在各个编译单元组合起来的时候)看的是bind属性,而不是vis属性,只有在链接动态库的时候才会看vis。
hidden的使用说明
一般是在做动态库的时候编译阶段传入下面的编译选项:
-fvisibility=hidden
这样可以让所有api都不能被使用,对于个别需要开放的api使用
int global_val __attribute__((visibility("default")));
注意
一个符号可以是global hidden的,也就是可以被其他目标文件链接,但是形成的动态库对外不可见。也可以是local default,这种对目标文件都不可可见,形成的动态库更加对外不可见。
参考
链接:https://stackoverflow.com/questions/22244428/hiding-symbol-names-in-library
The visibility(“hidden”) attribute does not suppress a symbol from an object file and cannot prevent a symbol being extracted by nm. It just instructs the dynamic linker that the symbol cannot be called from outside a shared library that contains it.