【问题标题】:Static and dynamic library linking静态和动态库链接
【发布时间】:2010-09-15 04:50:01
【问题描述】:

在 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 上进行链接,它可以毫无问题地链接。

【问题讨论】:

  • 根据 msdn,LINK 默认会删除未引用的打包函数(就像您使用 /OPT:REF 一样)。

标签: c++ linker aix


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    试试看吧....

    【讨论】:

    • xlc 的链接器比较棘手,虽然...从左到右的链接线大部分都可以工作,但实际上,所有内容都加载到内存中,然后进行图形遍历以满足链接。它比旧式链接更贵,但链接线不必订购。它也以有趣的方式打破
    • 我认为这不是问题,因为 1. 我尝试了不同的顺序和 2. Foo 未被任何其他库使用。
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

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

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

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

      【讨论】:

      • 我已经在寻找我错过的任何东西。 Foo 仅由 A 中的一个类在 C 不包含的文件中使用。所涉及的所有类都没有被导出。链接器抱怨 Foo 中的特定方法,例如Foo::DoThis() Foo::DoThat()。
      【解决方案5】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-23
        • 2011-03-16
        • 1970-01-01
        • 1970-01-01
        • 2015-07-10
        • 1970-01-01
        • 2020-01-13
        • 1970-01-01
        相关资源
        最近更新 更多