2011-04-04 119 views
1

我想链接静态库(.a)文件与.o文件,它应该使用库中的符号。但是,使用gcc时 - 正常的链接器错误出现,无论使用.a文件为g ++ vs gcc,链接问题与静态库(.a)

gcc -L。 a.c staticlib.a

但是,相同的命令完美地工作于g ++。

这是怎么发生的?

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

尝试使用objdump查找库中的符号,能够找到非常相似的符号,但不是确切的符号。 e.g:

了 00000000000000b0 G + F的.text 000000000000004e _ * Z15PhttsFn_InitTTSPh * 的符号* PhttsFn_InitTTS *

是否有人可以解释这种现象?我也检查过编译库文件的体系结构,它与我的体系结构相同。

谢谢!

+0

它看起来像你的库被编译为C++,因此符号名称被“破坏”,并且入口点只能被C++代码访问。 – 2011-04-04 10:55:14

+1

“完全合法的c(因此C++)”C不是C++的子集。 – alternative 2011-04-04 10:55:44

+0

感谢您的答案保罗:) Mathepic,对不起 - 我看到的单词的选择很差 - 现在我想起了一些合法的C代码在C++中是非法的,例如void指针赋值给另一种类型的指针等 – Anonymous 2011-04-04 15:10:05

回答

3

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

您的C代码明确引用了符号PhttsFn_InitTTS。现在如果编译为C,它将生成该符号的名称。但是,由于C++需要处理同名的所有这些不同变体(例如,使用不同的参数列表进行重载),因此它会创建一个“损坏的”版本编码名称空间和参数类型。在你的情况下,它被摧毁到Z15PhttsFn_InitTTSPh,基本上说没有命名空间和参数。 (我认为Z15意味着15个字符的名称,后面没有参数列表)。

调用GCC作为gcc允许它挑选文件格式本身,基于文件扩展名(.c - > C,或.cc.cpp等 - > C++)。将其作为g ++强制使用C++模式。

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

+1

nice - now你提到了捣毁 - 我记得前一阵子在C++的旋风版本中阅读过它,显然没有足够让我去调试它。非常感谢您的回答! – Anonymous 2011-04-04 15:09:14