你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

Linux下编译链接动态库符号问题

2022/1/1 9:49:04

一般大型的项目会有许多个动态库、静态库。许多个库可能会有符号冲突的问题,如果不对符号进行管理,会引发各种意想不到的问题。 

一、隐藏静态库的符号

参数:-Wl,--exclude-libs,ALL

应用场景:A.so 依赖了B.a,A.so不想对外提供B.a中的接口。

解决的问题:A.so和C.so同时依赖的B.a,如果B.a中有一个全局变量,并提供了两个函数Set和Get。此时,A调用Set后再调用Get,可能会Set调用的是A中的,Get调用的是C中的,导致程序运行不符合预期。这个问题也告诉我们静态库要设计成无状态的、幂等的。

二、链接时执行全链接

参数:-Wl,-z,defs

解决问题:动态库编译没问题,但是动态加载时提示undefined reference to错误:

A.so中定义了funcA但是没有实现,此时已然可以连接通过。但是在运行期间如果跑到了funcA,就会引发程序崩溃并且不产生core文件。

参考: 动态库编译加入参数:-Wl,-z,defs 编译期即可发现undefined reference to错误_tl_sunshine的博客-CSDN博客_-z,defs

三、隐藏符号

参数:-fvisibility=hidden

另外在需要导出的函数、类名前添加:__attribute__ ((visibility("default")))

应用场景:A.so只想暴露对外提供的符号。许多符号只运行内部使用。

解决问题: 多个库定义了相同的符号,运行时交叉调用导致功能异常。比如A.so和B.so都定义了func,但是A的func和B的func的实现是不一致的。如果两个符号都对外暴露了,运行期间可能会调用到非预期的func。

注意:隐藏符号,在某些情况下可能会引起单例变多例的问题。