程序是否需要.so共享库中的其他符号,但头文件中声明的符号除外?

时间:2010-03-03 08:48:02

标签: c symbols libraries shared

在C编程中,我认为只要.so文件提供了在头文件中声明的所有符号,就可以将目标文件与.so文件成功链接。

假设我有foo.c,bar.h和两个库libbar.so.1和libbar.so.2。 libbar.so.1和libbar.so.2的实现完全不同,但我认为只要它们都提供在bar.h中声明的函数就可以了。

我将foo.o与libbar.so.1链接并生成了一个可执行文件:foo.bin。当libbar.so.1在LD_LIBRARY_PATH中时,此可执行文件有效。(当然,符号链接是libbar.so)但是,当我将符号链接更改为libbar.so.2时,foo.bin无法运行并抱怨此:

 undefined symbol: _ZSt4cerr

libbar.so.1是一个c ++构建的库,而libbar.so.2是一个c构建的库。我不明白为什么foo.bin需要那些仅在libbar.so.1本身有意义的c ++相关符号,因为foo.bin是基于纯c代码foo.c构建的。

4 个答案:

答案 0 :(得分:3)

_ZSt4cerr显然是一个受损的C ++名称。您可能需要检查您是否使用了正确的编译器(gcc / g ++,我知道这听起来很愚蠢,但我碰巧遇到了这样的混乱;)),如果bar.h文件中有任何宏可能有引用了cerr。

答案 1 :(得分:2)

您必须在搜索之前解压缩c ++名称。对于gcc,有一个c ++ filt实用程序:

$ c++filt
_ZSt4cerr
std::cerr

这只是标准错误文件流。

答案 2 :(得分:0)

您可能只是忘了将整个程序与C ++标准库链接起来。

答案 3 :(得分:0)

问题中的陈述是错误的。你说,'头文件'。没有“ (唯一的)头文件。”如果你的意思是'声明某个C ++类的头文件',那么该类可能会从其他类继承。或者它可能会使用例外。或者RTTI。在这种情况下,默认情况下,包含与其一起使用的代码的.so将包含“悬挂未定义的符号”。默认情况下,期望“main”程序使用C ++,并链​​接到C ++运行库。

可能创建一个自包含的.so,但你必须做额外的工作才能创建它。您可能需要使用-Bsymbolic,或在链接时指定一些-l库,或两者都指定。这个区域没有详细记录,通常需要一些考古学。