为什么这种特殊情况会导致符号链接错误

C++ Why does this specific situation cause a symbol linking error?

本文关键字:符号链接 错误 情况 为什么      更新时间:2023-10-16

我正在开发一个应用程序,其中有一个'核心'和多个插件。我在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,为什么Plugin也必须"知道"LibB呢?为什么在所有情况下都不会发生此错误(即没有与LibC未定义符号相关的错误)?

我很感激你的建议。

kf

您必须记住,静态库只不过是打包成单个文件的目标文件的集合。如果你的插件需要LibA,而LibA需要LibB和LibC,那么当你链接你的插件时,你必须告诉链接器LibA, LibB和LibC在哪里。

如果你使用的是动态库,那就不一样了。A .so已经被链接了,所以它的所有引用都已经被解析了。如果LibA是一个动态链接库,那么你的插件只需要链接到LibA。因此,由于已经发生了链接步骤,将LibA绑定到它自己的依赖项。

如果静态库要包含来自它们的静态依赖的符号,那么由于定义了多个符号,您将得到各种讨厌的警告和错误。

考虑以下情况:

  • libA依赖于libB和libC
  • => libB depend on libD
  • => libC depend on libD

至少这是我在MSVS世界的经验。