在C ++中,静态库A链接到动态库B和C.如果在B中定义的A中使用了一个类Foo,如果它不使用Foo,它会链接吗?
我认为答案是肯定的,但是现在我遇到了xlc_r7的问题,其中库C说Foo是一个未定义的符号,就C而言。我的问题是库C没有使用引用它的类。这链接在Win32(VC6)和OpenVMS中。
这是链接器差异还是PBCAK?
新信息:
B取决于C,但反之亦然。
我没有使用/ OPT:REF链接在Windows上,它没有问题链接。
答案 0 :(得分:4)
静态链接时,两个模块成为一个模块。因此,当您编译C并将A链接到其中时,就好像您已将A的所有源代码复制到C的源代码中,然后编译组合的源代码。所以C.dll包括A,它依赖于B通过Foo。您需要将C链接到B的链接库以满足该依赖关系。
请注意,根据您的信息,这将在B和C之间创建循环依赖关系。
答案 1 :(得分:0)
听起来它可能是链接器(ld / unix),因为(我使用的大多数版本)ld从左到右链接库 - 如果在第一个中有一个引用,则需要稍后,通常的技巧是将第一个库(或任何所需的库)附加到命令的末尾。
试一试,看看......
答案 2 :(得分:0)
您的C链接是否包含B的导出库?如果是这样,理查德认为这听起来像是一个有序的东西。
另一个建议是查看是否有一个链接器选项来忽略未引用的符号,如果C不需要来自A的那个功能。对于使用/ OPT:REF开关实现的Microsoft链接器。
答案 3 :(得分:0)
C不会链接的唯一原因是编译器认为 需要Foo符号。
由于C不引用Foo符号,因此链接器需要符号的另一个原因是。
我所知道的另一个原因是某种出口。我只知道Visual C ++,所以我建议你在预处理文件中搜索一些等价的__declspec( dllexport )
,看看是什么产生的。
这就是我要做的事情:将预处理器输出存储在一个单独的文件中,然后搜索它以查找Foo的出现。它可以作为导出出现,也可以由编译器以某种方式引用。
答案 4 :(得分:0)
如果不需要特定功能的定义,则在链接阶段不会链接该库。在您的情况下,因为foo的定义存在于库B中而不存在于库C中。因此,在加载可执行文件时,库C将不会被加载到内存中。
但是看起来,你在库C中也使用了foo()函数,因为你得到了相应的错误。