C++为什么这种特定情况会导致符号链接错误?
我正在开发一个有“核心”和多个插件的应用程序。我在 Linux 上使用 Qt,并且使用 Qt 的插件加载器系统。插件被创建为共享对象文件 (*.so) 并动态加载。如果我链接到带有插件的库,并且该库链接到其他库,我经常会从应用程序中收到“未定义符号”错误。为了解决这个问题,我还需要将插件链接到其他库...
插件链接到 LibA
LibA 链接到 LibB,LibC
LibA 编译为静态。当我尝试加载插件时,我会得到一个未定义的符号错误,如下所示:
unable to load shared library 'myPluginName.so':
myPluginName.so: undefined symbol: _ZN3BlahBlahD2Ev
要解决此问题,我可以使用 filt 来解析符号名称,找出符号所属的库(例如 LibB),然后像这样编译:
插件链接到LibA,LibB
LibA链接到LibB,LibC
我不知道为什么会发生错误。如果 LibA 链接到 LibB 和 LibC,为什么插件也必须“了解”LibB?为什么这个错误不是在所有情况下都会发生(即没有与 LibC 未定义符号相关的错误)?
我将不胜感激任何意见。
-kf
I'm working on an application where there's a 'core' and multiple plugins. I'm using Qt on Linux, and I use Qt's plugin loader system. Plugins are created as shared object files (*.so) and loaded dynamically. If I link to a library with a plugin, and that library links to additional libraries, I often get an 'undefined symbol' error from the application. To get around it, I need to link the plugin to the additional libraries as well...
Plugin links to LibA
LibA links to LibB, LibC
LibA is compiled as static. When I try to load the plugin, I'll get an undefined symbol error, like so:
unable to load shared library 'myPluginName.so':
myPluginName.so: undefined symbol: _ZN3BlahBlahD2Ev
To fix this I can use filt to unmangle the symbol name, figure out which lib the symbol belongs in (say LibB), and then compile like:
Plugin links to LibA, LibB
LibA links to LibB, LibC
I don't know why the error occurs. If LibA links to LibB and LibC, why should Plugin have to 'know' about LibB as well? Why doesn't this error occur in all cases (ie no errors related to undefined symbols with LibC)?
I'd appreciate any input.
-kf
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您必须记住,静态库只不过是打包到单个文件中的对象文件的集合。如果您的插件需要 LibA,而 LibA 需要 LibB 和 LibC,那么当您链接插件时,您必须告诉链接器 LibA、LibB 和 LibC 在哪里。
如果您使用动态库,情况就会有所不同。 .so 已经链接,因此它的所有引用都已解析。如果 LibA 是动态链接库,那么您的插件只需要链接 LibA.so,因为已经发生链接步骤将 LibA 绑定到其自己的依赖项。
You have to keep in mind that a static library is nothing more than a collection of object files packaged together into a single file. If your plugin needs LibA, and LibA needs LibB and LibC, then when you link your plugin you have to tell the linker where LibA, LibB and LibC are.
If you work with dynamic libraries it would be a different story. A .so is already linked, so all its references were already resolved. If LibA was a dynamically linked library then your plugin would only need to link against LibA.so, since a link step already occurred to bind LibA to its own dependencies.
如果静态库要包含来自其静态依赖项的符号,那么由于多重定义的符号,您将收到各种令人讨厌的警告和错误。
考虑这种情况:
至少这是我在 MSVS 领域的经验。
If static libraries were to include symbols from their static dependencies, you would get all sort of nasty warnings and errors due to multiply defined symbols.
Consider the case:
At least that's my experience from the MSVS world.