静态和动态库链接

问题描述:

在C++中,静态库A链接到动态库B和C中。如果在B中定义的A中使用了类Foo,那么C链接是否会使用Foo?静态和动态库链接

我认为答案是肯定的,但是我现在遇到了一个xlc_r7问题,其中库C说Foo是一个未定义的符号,就C而言。我的问题是库C不使用引用它的类。这在Win32(VC6)和OpenVMS中链接。

这是链接器差异还是PBCAK?

新信息:

  1. B依赖于C,但不是反之亦然。

  2. 我没有使用/ OPT:REF链接在Windows上,它没有问题的链接。

+0

根据msdn,LINK默认删除未引用的打包函数(就像您使用/ OPT:REF一样)。 – xtofl 2008-10-04 18:49:20

当你静态链接时,两个模块成为一个。因此,当您编译C并链接到它时,就好像您已将A的所有源代码复制到C的源代码中,然后编译组合的源代码。所以C.dll包含A,它通过Foo依赖于B。您需要将C链接到B的链接库以满足该依赖关系。

请注意,根据您的信息,这将创建B和C.

听起来像它可能是连接器(LD/UNIX),作为LD链接从左至右库(即我使用的大多数版本) - 如果没有在第一个的参考这是后面的要求,通常的技巧是将第一个库(或任何所需的库)追加到命令的末尾。

这是一个尝试,看看....

+0

虽然xlc的链接器很棘手,但是......从左到右的链接线大部分都能正常工作,但实际上,所有内容都被加载到内存中,然后完成图形漫步以满足链接。它比旧式链接更昂贵,但链接线不必订购。它也以有趣的方式打破 – 2008-10-04 01:01:56

+0

我不认为这是问题,因为1.我尝试了不同的顺序和2.Foo没有被任何其他库使用。 – Jake 2008-10-05 03:45:57

是对C您的链接线包括出口LIB对于B?如果是这样,理查德建议它听起来​​像一个订购的东西。

另一个建议是查看是否有链接器选项忽略未引用的符号,如果C不需要A的功能。对于Microsoft链接器,这通过/ OPT:REF开关实现。

的唯一原因之间的循环依赖为什么C将不链接是编译器认为它确实需要的富象征。

因为C没有引用Foo符号,所以链接器需要该符号必须有另一个原因。

我知道的唯一的其他原因是某种出口。我只知道Visual C++,所以我建议你在预处理的文件中搜索一些等效的__declspec(dllexport),并查看它生成的内容。

下面是我要做的:将预处理器输出存储在一个单独的文件中,并搜索Foo的出现次数。要么它会作为导出出现,要么被编译器以某种方式引用。

如果不需要特定函数的定义,那么在链接阶段不会链接该库。在你的情况下,由于foo的定义存在于库B中,而不是库C中。因此,在加载可执行文件时,库C将不会加载到内存中。

但是看起来,你也在库C中使用了foo()函数,因为你正在得到相应的错误。