【发布时间】:2019-08-23 23:08:03
【问题描述】:
我有一个看起来像这样的项目:
executable
\---> bsp.so
|---> bsp_protobuf.a
\---> protobuf.a
其中有两个首先构建的静态库(两个 protobuf 的)静态链接到 bsp.so 共享库。然后最后将 bsp.so 链接到可执行文件中。
当我在命令行上使用 gcc 链接可执行文件和链接 bsp.so 时,链接正常。
但是,如果我 不 链接 bsp.so 那么它也可以正常构建 - 这是设计使然 - 因为我想使用 dlopen() 来确定我是否需要这个库(我有指针到对象,但没有实例化等...)。
我遇到的问题是,当我使用dlopen()(在代码中)时,由于未定义的符号,它无法打开库。有问题的符号位于静态库中。
我真正难以理解的是为什么它在命令行上有效,但在我使用 dlopen() 和运行时无效。
我有 3-4 个其他共享库可以成功使用 dlopen() - 所以我知道我使用 dlopen() 的一般过程很好。
我正在使用dlerror() 来获取未定义符号的错误消息。
我查看了以下链接:
how-to-force-symbols-from-a-static-library-to-be-included-in-a-shared-library-bu
how-to-apply-fvisibility-option-to-symbols-in-static-libraries
我绑定了-Wl,--whole-archive 的想法,但这似乎牵扯太多,构建失败并出现太多警告 - 可能与 google protobuf 的东西有关,而且我不确定这是我想要的方法以结束。
我检查了我的共享库是用-fPIC 构建的,我不确定静态库是用-fPIC 构建的还是需要的?
我也看过这里:
其中讨论了如何与 dlopen() 链接,但这是使用 libtools - 我们的所有目标都没有这个,所以我不想使用 libtools。
我真的不确定要采用哪种方法 - 感觉这应该是一个简单的解决方法 - 但正如我所说,我无法理解为什么一种方法有效而另一种方法无效......
更新
所以,在 Sam 的评论之后,我开始寻找正确的地方。事实证明,bsp.so 的 makefile 仅静态链接两个库之一。 该共享库有一个单独的测试器,它链接两个库(因此测试器工作),我没有理由怀疑 lib 被破坏了......好吧,我学到了很多关于 dlopen 和链接等的知识......:o
【问题讨论】:
-
你在链接.so时试过
-Wl,--no-undefined吗?我相信,它可能会对你有所帮助。 -
与共享库链接检查可执行文件的外部符号是否被它链接的所有共享库解析。如果共享库使用其他未解析的外部符号,则不会检查。在据称成功将其与此共享库链接后尝试运行可执行文件。你会得到同样的错误。
-
@SamVarshavchik 啊,你说得对!这对我来说是一个大红鲱鱼。现在我知道它与 dlopen 无关我发现了明显的问题 - 非常感谢,请添加为答案,这样我就可以投票一百万次! (好吧,一次就可以了)
-
@SergeyA 感谢您的意见 - 我没有尝试它,因为在意识到我的 gcc 链接版本无法正常工作后,我发现了可怕的错误,正如 Sam 指出的那样
标签: c++ gcc dynamic-linking dlopen