【发布时间】:2017-03-09 18:18:48
【问题描述】:
背景: 我正在尝试提供一个包装在接口中的库,以在第三方应用程序 (MATLAB) 中使用。 我的问题是我的库和第三方应用程序都依赖于 Boost 库。
更糟糕的是,它们不仅依赖于两个不同版本的 Boost,而且我的库是针对 Boost 的补丁版本构建的,并且它们是静态链接的。相反,第三方库是针对 Boost 动态链接的。
这就是我链接的方式(make -n 的简化输出)
g++ -fPIC ${CPPFLAGS} -shared -lc -ldl ... -Wl,-h,mylib.so -o mylib.so \
${MYSTATICLIBS} \
-L${MATLABLIBSPATH} -lmx -lmex \
-L${MYBOOSTVERSIONPATH} -lboost_thread-gcc49-mt-1_52 ...
然后,当我在 MATLAB 中运行库 fron 时,从我的内部函数调用了错误的 boost 函数(并且一切都崩溃了)。
我的直觉是,因为我静态链接了我的 Boost,所以从我的库中对它们的所有调用都应该指向我的 Boost,而来自 libmx.so 或 libmex.so 的调用将指向它们动态加载的依赖项。然而,这证明我天真的直觉是非常错误的。
我在 SO 和网络上发现了不同的提示,描述了链接顺序如何破坏类似情况,但是所有内容都描述了冲突符号的所有静态或所有动态链接。
建议的解决方案是
- 使用 -Bsymbolic -Bsymbolic-functions
- 将我的库升级到相同的 boost 版本
- 更改链接顺序(首先是 boost,然后是 -lmx -lmex)
- 卖掉我所有的尘世财产,在炎热的海滩上买一个酒吧,然后尝试以此谋生
- 其他??
有人可以解释这些解决方案是否以及为什么有效? (我的另一个问题是,我自己无法使用 MATLAB 进行测试,因为我无法访问安装它的机器。这就是为什么我还要问“是否”提出的解决方案可行)
【问题讨论】:
-
“它们是静态链接的” - 你 100% 确定你链接到静态版本的 Boost 吗?
readelf --dyn-syms -W youlib.so的输出是否显示定义的 Boost 符号(而不是“UND”)?