简体   繁体   English

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

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

I have a project that looks like this: 我有一个看起来像这样的项目:

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

Where there are two static libraries that get build first (the two protobuf ones) that are statically linked into the bsp.so shared lib. 其中有两个首先构建的静态库(两个protobuf库)被静态链接到bsp.so共享库中。 And then finally bsp.so is linked into executable. 然后最后bsp.so被链接到可执行文件。

When I link executable and link bsp.so using gcc on the command line it links ok. 当我在命令行上使用gcc链接可执行文件并链接bsp.so时,它链接确定。

However if I dont link bsp.so then it also builds fine - this is by design - because I want to use dlopen() to determine if I need this library or not (I have pointers to the objects, but none that are instantiated etc...). 但是,如果我链接bsp.so,那么它也可以正常构建-这是设计使然-因为我想使用dlopen()来确定是否需要该库(我有对象的指针,但没有实例化的指针等) ...)。

The problem I have is that when I use dlopen() (in the code) it fails to open the library due to an undefined symbole. 我的问题是,当我在代码中使用dlopen() ,由于未定义符号而无法打开库。 The symbol in question lives within the static librarys. 有问题的符号位于静态库中。

What I really struggle to understand is why it works on the command line but does not work when I use dlopen() and runtime. 我真正难以理解的是,为什么它在命令行上起作用,但是当我使用dlopen()和运行时却不起作用。

I have 3-4 other shared libs that I can successfully use dlopen() on - so I know my general process for using dlopen() is good. 我还有其他3-4个可以成功使用dlopen()共享库-因此,我知道使用dlopen()一般过程很好。

I am using dlerror() to get the undefined symbol error message out. 我正在使用dlerror()来获取未定义的符号错误消息。

I have looked at the following links: 我看了以下链接:

how-to-force-symbols-from-a-static-library-to-be-included-in-a-shared-library-bu 如何对力符号从-一个静态库-待包括-IN-A-共享库-BU

how-to-apply-fvisibility-option-to-symbols-in-static-libraries 如何对申请-fvisibility选项至符号功能于静态库

I tied the -Wl,--whole-archive idea, but that seemed to pull in too much and the build failed with soooo many warnings - probably somthing more to do with the google protobuf stuff, plus I am not sure that is the approach I want to end up with. 我把-Wl,--whole-archive想法捆绑在一起,但是似乎太多了,并且构建失败并发出了很多警告-可能与Google protobuf东西有更多关系,再加上我不确定这是什么方法我想结束了。

I checked that my shared lib was built with -fPIC , I am not sure if the static libs are build with -fPIC or if they need to be? 我检查了我的共享库是使用-fPIC ,我不确定静态库是否是使用-fPIC或者是否需要?

I also looked here: 我也在这里看:

libtool_9.html libtool_9.html

which discusses how to link with dlopen() but this is using libtools - we don't have that for all of our targets so I don't want to use libtools. 其中讨论了如何与dlopen()链接,但这使用的是libtools-我们的所有目标都没有,所以我不想使用libtools。

I am really not sure which way to progress - it feels like this should be a simple fix somewhere - but as I say, I can't get my head around why one method works and the other does not... 我真的不确定前进的方向-感觉这应该是某个地方的简单修复-但正如我所说,我无法理解为什么一种方法有效而另一种无效...

Update 更新

So, after Sam's comment I started to look in the right place. 因此,在Sam发表评论后,我开始寻找正确的地方。 It turns out the makefile for bsp.so statically links only one of the two libraries. 事实证明,bsp.so的makefile仅静态链接两个库之一。 There is a seperate tester for that shared lib that links both libraries (and so the tester works) and I had no reason to suspect that lib was broken... well, I learnt quite alot about dlopen and linking etc... :o 对于共享的库,有一个单独的测试程序可以链接两个库(因此测试程序可以正常工作),而且我没有理由怀疑该库已损坏……好吧,我在dlopen和链接等方面学到了很多知识::o

When you link an executable with shared libraries, unresolved symbol references from the executable must be resolved by the shared libraries, otherwise the link fails. 当您将可执行文件与共享库链接时,共享库必须解析来自可执行文件的未解析符号引用,否则链接将失败。

When you link a shared library, it is not required that all of the unresolved symbol from the shared library itself must be resolved by any other shared library that it links with; 当您链接共享库时,不需要共享库本身中所有未解析的符号都必须由与其链接的任何其他共享库来解析。 therefore when you link together a shared library it's possible to wind up with unresolved symbols from the shared library itself. 因此,当您将共享库链接在一起时,可能会出现共享库本身中未解析的符号的情况。

Linking an executable with the shared library succeeds because all unresolved symbols in the executable get resolved by the shared library; 将可执行文件与共享库链接成功,因为共享库中解析了可执行文件中所有未解析的符号; but the executable will fail to load due to unresolved symbol references from the shared library itself. 但是由于共享库本身无法解析的符号引用,可执行文件将无法加载。 Alternatively, dlopen ()ing the shared library produces the same error. 或者,对共享库进行dlopen ()处理会产生相同的错误。

The dlopen manual page also describes several optional flags that can be used to control this behavior. dlopen手册页还描述了几个可用于控制此行为的可选标志。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM