现象:程序中的一个类和动态库中的一个类同名,编译以后程序运行过程中崩溃,出现段错误。gdb调试发现,在我们的动态库A.so中有个接口叫QByteArray,我们调用的底层还有个用的别人提供的动态库B.so,其中有个类也叫QByteArray(qt库提供的),最终的问题就是本应该进入A.so中QByteArray程序进入到了B.so中的QByteArray了。
验证:在linux环境下,如果发生这种同名情况,自己程序中同名的类会覆盖动态库中的,使程序从动态库退出。
gcc在链接时,如果有一个动态库模块定义了某个符号,那么后面其他动态库中同名符号都会被忽略!
同名函数均改成static,那么两个库中的同名函数也不会冲突,因为静态函数只能被本模块引用制作成静态库,但是在链接时就会报符号重定义的错误。
处理方法:
1.为函数增加命名空间。因为增加了命名空间之后,两个库中的导出符号不同了。
2.在写代码过程中尽量避免这种同名;
3. 利用编译方法:将发生重名的那个动态库编译时加上编译选项:-fvisibility=hidden(使用该选项编译出的.o文件中所有符号均为外部不可访问)。
4. 添加gcc / g++编译选项: -Wl,-Bsymbolic
-Wl,-Bsymbolic (不要少逗号)
这个是在gcc/g++编译的一个选项,其中Wl表示将紧跟其后的参数,传递给连接器ld。Bsymbolic表示强制采用本地的全局变量定义,这样就不会出现动态链接库的全局变量定义被应用程序/动态链接库中的同名定义给覆盖了!
另外:visibility(visibility用于设置动态链接库中函数的可见性,将变量或函数设置为hidden,则该符号仅在本so中可见,在其他库中则不可见;若设置为default,则在其他库中也可见。使用方法参见:visibility)但是没有效果。