使用C和C++库混合编程

4
我有一个奇怪的问题,正在构建一个使用C ++库(该库本身依赖于C库)的可执行文件的代码。我使用gcc编译了组成C库的C模块,同时使用g ++编译了所有其他源模块。 C库和C ++库都是静态库。
当我在C ++源代码中包含C库的头文件时,我总是用extern "C"将其包装:
extern "C"
{
  #include <c-library-header.h> 
}

现在的奇怪之处在于链接时出现了“undefined reference”错误,但这些错误会根据我列出库的顺序而改变:
如果先列出C库,那么所有由C++模块引用的库中符号将显示为“未定义”。
如果先列出C++库,那么所有由C++模块引用的库中符号将显示为“未定义”。
我本来认为在g++命令行中静态库出现的顺序是完全无关紧要的。有人有什么线索吗?
2个回答

7

对于一个很好的答案点个赞。不过这让我感到惊讶。微软做得很好,因为它的链接器不需要我担心这些愚蠢的细节。 - pete

2

如果有很多相互依赖的库,反复列出这些库可能会很麻烦,此时可以依靠GNU ld来搜索库列表,直到所有符号都得到解析。这可以通过使用start_group/end_group命令行开关来实现:

g++ <...flags...> -Wl,--start-group -lxxx -lyyy -Wl,--end-group <...other flags...>

或者直接提供档案,如果它们以“不符合规范”的方式命名:

g++ <...flags...> -Wl,--start-group xxx.a yyy.a -Wl,--end-group <...other flags...>

这样一个很好的功能需要付出的代价是降低链接速度,在许多情况下,这不是关键问题。

只是想说,-Wl, 这一部分很重要。我最初在 GCC 的手册中找到了 --start-group,但如果你忘记了 -Wl,,它就会悄悄地跳过它,没有错误信息。我一直无法弄清楚为什么它不能按照文档所述工作。 - M.M
有人知道为什么GNU ld不默认进行多次通行吗? - M.M
因为它在大链接上速度较慢,并且在小链接上很少需要。 - oakad
只有在第一次通过后仍存在未解决的符号时,您才需要这样做,因此它不会减慢本来可以正常工作的任何东西。 - M.M
好的,你不是第一个对这个确切问题感到困惑的人:http://stackoverflow.com/questions/16838719/why-does-the-gnu-linker-not-default-to-grouped-libs :) - oakad
你是第一个回答的人,显然 :) - M.M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接