gcc 链接共享库有效,但同一共享库的 dlopen 失败

gcc linking shared library works, but dlopen of the same shared lib fails

我有一个看起来像这样的项目:

executable
    \---> bsp.so
           |---> bsp_protobuf.a
           \---> protobuf.a

其中有两个首先构建的静态库(两个 protobuf 库)被静态 linked 到 bsp.so 共享库中。最后 bsp.so 被 link 编辑成可执行文件。

当我 link 可执行文件和 link bsp.so 在命令行上使用 gcc 时 link 没问题。

但是,如果我 dont link bsp.so 那么它也可以正常构建 - 这是设计使然 - 因为我想使用 dlopen()确定我是否需要这个库(我有指向对象的指针,但是 none 实例化等...)。

我遇到的问题是,当我使用 dlopen()(在代码中)时,由于未定义的符号,它无法打开库。有问题的符号位于静态库中。

我真正难以理解的是为什么它在命令行上有效,但在我使用 dlopen() 和运行时时却不起作用。

我还有 3-4 个可以成功使用 dlopen() 的其他共享库 - 所以我知道我使用 dlopen() 的一般过程很好。

我正在使用 dlerror() 来获取未定义符号错误消息。

我看过以下link:

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 构建的还是需要?

我也看过这里:

libtool_9.html

讨论了如何 link 与 dlopen() 但这是使用 libtools - 我们没有为我们的所有目标提供它,所以我不想使用 libtools。

我真的不确定要采用哪种方法 - 感觉这应该是某个地方的简单修复 - 但正如我所说,我无法理解为什么一种方法有效而另一种方法无效.. .

更新

所以,在 Sam 的评论之后,我开始寻找正确的地方。事实证明,bsp.so 的 makefile 静态 link 只是两个库之一。 该共享库有一个单独的测试器,link 有两个库(因此测试器可以工作),我没有理由怀疑库已损坏......好吧,我学到了很多关于 dlopen 和 linking 等...:o

当您 link 具有共享库的可执行文件时,来自可执行文件的未解析符号引用必须由共享库解析,否则 link 失败。

当您 link 一个共享库时,不需要共享库本身的所有未解析符号都必须由它 link 与之相关的任何其他共享库解析;因此,当您 link 将共享库放在一起时,可能会从共享库本身中得到未解析的符号。

将可执行文件与共享库链接成功,因为可执行文件中所有未解析的符号都由共享库解析;但由于来自共享库本身的未解析符号引用,可执行文件将无法加载。或者,dlopen()ing 共享库会产生相同的错误。

dlopen 手册页还介绍了几个可用于控制此行为的可选标志。