2010-07-29 93 views
26

在今天之前,我始终认为在链接阶段,对象和库传递给g ++的顺序并不重要。然后,今天,我试图从C++代码链接到c代码。我把所有的C头文件都封装在一个extern“C”块中,但是链接器仍然很难找到我知道的C对象存档中的符号。将c代码链接到C++代码时,g ++链接顺序依赖关系

困惑,我创建了一个相对简单的例子来隔离链接错误,但让我吃惊的是,更简单的例子没有任何问题。

经过一些试验和错误,我发现通过模拟简单例子中使用的链接模式,我可以得到主代码链接OK。这种模式是目标代码首先,对象档案第二例如:

g++ -o serverCpp serverCpp.o algoC.o libcrypto.a

任何人都可以阐明为什么这可能是这样一些轻?链接普通C++代码时,我从来没有见过这个问题。

+0

有关详细信息,请参阅:http://stackoverflow.com/questions/1095298/gcc-c-linker-errors-undefined-reference -to-vtable-for-xxx-undefined -referen/1095321#1095321 – 2010-07-29 17:23:39

回答

35

您指定目标文件和库的顺序在GCC中非常重要 - 如果您在引导一个充满魅力的生活之前没有被此刻咬过。链接器按照它们出现的顺序搜索符号,所以如果你有一个包含对库函数调用的源文件,你需要把它放在库之前,否则链接器不会知道它必须解决它。图书馆的复杂使用可能意味着你不得不多次指定图书馆,这是一个皇家的痛苦。

+0

相信我,我没有:-),有没有关于这个属性的任何文档? – 2010-07-29 14:17:47

+0

这里我们去:http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html – 2010-07-29 14:20:14

+0

我也总是发现链接顺序是至关重要的;它可能很难解决为什么链接错误也发生,直到你猜测订单是错误的... – 2010-07-29 14:22:19

6

静态库是分组到档案中的对象文件的集合。链接时,链接器只选择它需要的对象来解析当前未定义的符号。由于对象按照命令行给定的顺序链接,因此只有在库依赖它的所有对象之后才会包含库中的对象。

所以链接顺序非常重要;如果你打算使用静态库,那么你需要注意跟踪依赖关系,并且不要在库之间引入循环依赖关系。

+0

循环依赖关系正常 - 仅仅意味着您需要像“'ao bo ao'”。 – caf 2010-07-30 11:45:41

+1

@caf:如果第二个列入的'a'的额外对象依赖于'b'中尚未包含的对象,那么这还不够好;你需要在最后加上'b'。这反过来又可能引入对'a'的更多依赖。所以循环依赖并不是真的“好”,对于他们来说病态足以需要一次以上的重复是很少见的。 – 2010-07-30 11:52:09

17

库命令传递给gcc/g ++确实很重要。如果A取决于B,则必须先列出A.原因是它优化了没有引用的符号,所以如果它首先看到库B,并且没有人在那个时候引用它,那么它根本就不会链接任何符号。

0

可以使用--start组档案--end组 和写入2个依赖库,而不是档案

的gcc main.o -L。 -Wl, - start-group -lobj_A -lobj_b -Wl, - end-group