共享对象库能否访问静态链接库中的对象?如何实现?
共享对象库访问主程序静态链接库符号的解决方案
核心结论
共享对象库可以访问主程序中静态链接库的符号,关键是让主程序导出这些符号供动态加载的共享库调用。
问题原因
你遇到的运行时错误本质是:默认情况下,主程序静态链接libUtils.a后,链接器不会将静态库的全局符号导出到主程序的动态符号表中,导致动态加载SheepPopWrapper.so时,无法找到_ZN10MessLogger17s_sCurHeaderErrorB5cxx11E这类符号。
具体解决方案
1. 编译主程序时导出全局符号
使用GCC/Clang编译主程序MainAppDyn时,添加-rdynamic(等价于-export-dynamic)参数,强制链接器将主程序的所有全局符号(包括静态链接的libUtils.a中的符号)加入动态符号表:
g++ -o MainAppDyn main.cpp libUtils.a -rdynamic
验证:执行以下命令查看主程序的动态符号表,确认目标符号已导出:
nm -D MainAppDyn | grep MessLogger17s
此时应该能看到该符号出现在输出中。
2. 编译共享库时避免重复链接静态库
编译SheepPopWrapper.so时,仅编译自身代码,不要链接libUtils.a,直接依赖主程序导出的符号:
g++ -shared -fPIC -o SheepPopWrapper.so SheepPopWrapper.cpp
这样共享库会在运行时从主程序的动态符号表中查找所需符号,不会生成libUtils的第二份实例,单例对象保持唯一。
关键原理
-rdynamic参数的作用是告诉链接器,将主程序的全局符号表暴露给后续动态加载的共享对象。默认情况下,链接主程序时只会保留自身执行所需的符号,不会对外暴露静态库的符号,导致动态加载的.so无法解析这些符号。
内容的提问来源于stack exchange,提问作者user1479670
相关产品推荐
相关产品推荐

