2

在 C++ 中,静态库 A 链接到动态库 B 和 C。如果在 B 中定义的 A 中使用了一个类 Foo,如果它不使用 Foo,C 会链接吗?

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

这是链接器差异还是 PBCAK?

新信息:

  1. B 取决于 C,但反之亦然。

  2. 我没有使用 /OPT:REF 在 Windows 上进行链接,它可以毫无问题地链接。

4

5 回答 5

4

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

请注意,根据您的信息,这将在 B 和 C 之间创建循环依赖关系。

于 2008-10-04T00:53:39.607 回答
0

听起来它可能是链接器(ld/unix),因为(我使用过的大多数版本)ld 将库从左到右链接到 - 如果第一个引用中有稍后需要的引用通常的技巧是将第一个库(或任何必需的库)附加到命令的末尾。

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

于 2008-10-03T21:40:49.670 回答
0

您的 C 链接行是否包括 B 的导出库?如果是这样,那么正如理查德所说,这听起来像是一个订购的东西。

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

于 2008-10-03T22:04:35.237 回答
0

C 不链接的唯一原因是编译器认为它确实需要 Foo 符号。

由于 C 不引用 Foo 符号,因此链接器需要该符号肯定还有另一个原因。

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

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

于 2008-10-04T11:21:16.517 回答
0

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

但似乎您也在使用库 C 中的 foo() 函数,因此您会收到相应的错误。

于 2017-03-10T10:39:27.513 回答