【问题标题】:g++ vs gcc, linking problem with a static library (.a)g++ vs gcc,与静态库(.a)的链接问题
【发布时间】:2011-04-04 10:52:21
【问题描述】:

我正在尝试将静态库 (.a) 文件与据称使用库中的符号的 .o 文件链接。但是,当使用 gcc 时 - 出现正常的链接器错误,无论使用 .a 文件作为

gcc -L。 a.c 静态库.a

但是,相同的命令可以完美地与 g++ 一起使用。

为什么会这样?

我可以看到 .c 文件是完全合法的 c(因此也是 c++),但是为什么 gcc 不能检测库中的符号?

尝试使用 objdump 在库中查找符号,能够找到非常相似的符号,但不是精确的符号。例如:

得到 00000000000000b0 g F .text 000000000000004e _*Z15PhttsFn_InitTTSPh* 对于符号 *PhttsFn_InitTTS*

有人可以解释一下这种现象吗?我还检查了编译库文件的架构,它与我的架构相同。

谢谢!

【问题讨论】:

  • 看起来你的库是用 C++ 编译的,因此符号名称是“损坏的”,入口点只能由 C++ 代码访问。
  • "完全合法的 c (以及 c++)" C 不是 C++ 的子集。
  • 感谢 Paul 的回答 :) Mathepic,抱歉 - 我看到的词选择不当 - 现在我想起来了,一些合法的 C 代码在 C++ 中是非法的,比如将 void 指针分配给另一个指针种类等

标签: gcc static g++


【解决方案1】:

C++ 使用称为名称修饰的东西,以便命名空间、重载函数名称等,以在编译的目标文件中获取唯一符号。

您的 C 代码明确引用了符号 PhttsFn_InitTTS。现在,如果编译为 C,它将产生那个符号名称。然而,由于 C++ 需要处理所有这些同名的不同变体(例如重载,使用不同的参数列表),它创建了一个“损坏的”版本编码命名空间和参数类型。在您的情况下,它被修改为Z15PhttsFn_InitTTSPh,基本上说没有命名空间和参数。 (我认为 Z15 表示 15 个字符的名称;后面没有参数列表)。

调用 GCC 为 gcc 允许它根据文件扩展名(.c -> C、.cc 或 .cpp 等 -> C++)自行选择文件格式。以 g++ 的形式调用它会强制执行 C++ 模式。

您的 .a 文件显然是使用 C++ 编译的,因为它暴露了那个损坏的符号。

【讨论】:

  • 很好 - 既然你提到了 mangling - 我记得不久前在 C++ 的旋风式修订中读到它,显然没有足够的坚持让我调试这个。非常感谢您这么清楚地回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-18
  • 1970-01-01
  • 2019-04-19
  • 1970-01-01
  • 1970-01-01
  • 2012-12-17
相关资源
最近更新 更多