静态和动态库链接

Static and dynamic library linking

本文关键字:链接 动态 静态      更新时间:2023-10-16

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

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

这是链接器差异还是PBCAK?

新信息:

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

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

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

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

听起来它

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

试一试,看看...

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

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

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

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

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

我要

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

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

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