繁体   English   中英

如何解决链接到 static 库的共享库中的 C++ 链接错误

[英]How to solve C++ linking error in shared library linked to a static library

我正在努力解决链接错误。 我有 3 个模块:

  • static 库 A 定义了 function ole::compound_document::find_storage(const std::string&);
  • 共享库 B 链接到 A 并使用 function;
  • 可执行 C 链接到 B 并使用 B 中的函数(但不直接调用库 A 的函数)。

在链接可执行文件 C 期间,我收到以下错误消息:

../../bin/B.so: undefined reference to `ole::compound_document::find_storage(std::string const&)'

function 在库 A 中定义。如果我在共享库 B 上运行实用程序nm ,我会收到以下 output:

0000000001841c70 T ole::compound_document::find_storage(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
                 U ole::compound_document::find_storage(std::string const&)

它显示了两个 find_storage 函数。 其中一个已定义,另一个未定义。 我试图了解它是如何发生的。 到目前为止没有成功。 问题出现在Linux(Ubuntu)下,编译器:clang-9。 在 Windows 上,我可以毫无问题地构建库和可执行文件。

我试图创建一个最小的例子,只是将 3 个简单的模块和几个函数放在一起。 一切正常。 编译器仅使用 function 的第一个定义。 我不明白第二个定义来自哪里。 我怀疑 c++ 标准的混合,但找不到任何东西。

任何建议将不胜感激。

您将需要在库 B 的代码中查找问题。 std::string逐字逐句不是从导出符号引用的实际类型,因为std::string只是std::basic_string实例的别名。 通过查看链接到库 B 的所有模块的符号来缩小范围,一旦确定了这样做的模块,您就需要找出原因。

您的问题没有提供足够的数据来决定性地识别链接问题,因为当然,这只能通过检查链接中涉及的所有 object 模块并检查所有源代码是否可能违反单一定义规则来完成,或格式错误的代码,没有产生诊断,但表现为链接故障。

因此,以下答案旨在作为隔离此类链接故障的一般指南。 我认为这个问题不符合规范答案的要求。

您在链接的共享库中有一个符号在链接到可执行文件时没有得到解析,特别是:

ole::compound_document::find_storage(std::string const&)

就像您在共享库上运行nm一样,您可以在进入共享库的每个模块上单独使用它。 这将找到未解析的引用来自哪个 object 模块。 如果你没有找到它,它一定来自你链接的 static 库,所以在那里重复你的搜索。

该参考来自您用于构建共享库的 object 模块之一。 您会以这种方式找到它,它不太可能突然出现。

找到相关模块后,您就可以自行查看已编译的实际代码,并找出发生了什么。 如果你想不通:分而治之。 拿object模块,把源文件拆分成两个文件,每个文件一半的函数,分别编译,然后看看哪里来的未解析的引用。

最后:在做这一切之前,先试试容易实现的结果: make clean ,然后重新编译一切。 这具有编译器开关的所有特征,一些 object 模块是由不同的编译器编译的。 如果该 static 库是由第三方供应商作为二进制 blob 提供的,则它一定是由不同的编译器或不同版本的编译器编译的。 C++ 不保证二进制 ABI 兼容性。

正如n所提到的。 '代词' m。 问题在于 -D_GLIBCXX_USE_CXX11_ABI 标志的使用不一致。 我使用了 c++14 标准,但是有些项目是用标志 -D_GLIBCXX_USE_CXX11_ABI=1 编译的。 这并不容易找到,因为我使用了很多带有柯南 package 管理器的 3rd 方库。

暂无
暂无

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

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