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

时间:2019-04-02 15:01:35

标签: c++ gcc dynamic-linking dlopen

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

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构建的?

我也在这里看过:

libtool_9.html

讨论了如何与dlopen()进行链接,但这是在使用libtools-我们的所有目标都没有,所以我不想使用libtools。

我真的不确定前进的方向-感觉这应该是在某个地方的简单修复-但正如我所说,我无法理解为什么一种方法有效而另一种无效... < / p>

更新

因此,在Sam发表评论后,我开始寻找正确的地方。事实证明,bsp.so的makefile仅静态链接两个库之一。 对于共享的库,有一个单独的测试程序可以链接两个库(因此测试程序可以正常工作),而且我没有理由怀疑该库已损坏……好吧,我在dlopen和链接等方面学到了很多知识::o

1 个答案:

答案 0 :(得分:1)

将可执行文件与共享库链接时,共享库必须解析来自可执行文件的未解析符号引用,否则链接将失败。

链接共享库时,不需要共享库本身与之链接的任何其他共享库都必须解析共享库本身中所有未解析的符号;因此,当您将共享库链接在一起时,可能会出现共享库本身未解析的符号的情况。

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

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