【问题标题】:No additional dependencies required for a LIB but are required for a DLLLIB 不需要其他依赖项,但 DLL 则需要
【发布时间】:2010-09-11 14:59:05
【问题描述】:

我有一个依赖于一些第三方库的框架(在 C++ 中)。我在编译library框架的静态版本时,不需要额外的依赖,即不需要第三方库的lib文件。当我编译与DLL 相同的框架时,现在需要额外的依赖项,否则会出现链接错误。我可以猜到为什么会发生这种情况,但想要一个具体的答案/解释来了解正在发生的事情。

编辑: 澄清一下,我正在开发一个框架,它可以编译为 libdllthen 在 a(n )(可执行)项目。将框架编译为lib 并使用第三方库中的函数时,我不需要额外的依赖项。但是,现在使用 lib 文件(即框架)的项目必须包含第 3 方 lib 文件。当我将框架编译为dll 时,它会给我链接错误,除非我指定框架在技术上依赖的第三部分库。例如:我有一些从 Ogre3D 中调用功能的类。这些类被编译为lib 文件。在编译类的lib 时,我不需要链接OgreMain.lib。另一方面,当我编译相同类的dll 版本时,我现在需要链接到OgreMain.lib

【问题讨论】:

  • 附加依赖是什么意思?
  • 也许我误读了一些东西,但我认为 Samaursa 是专门针对他正在编译的情况提出的,而不是询问确定运行时依赖关系。听起来他的项目有两种配置,“build as DLL”和“build as static DLL”。

标签: c++ dll static-libraries


【解决方案1】:

如果您有一个静态库(.lib 文件),它只是一个或多个目标文件 (.obj) 的集合,链接器只会将该代码添加到您的一个可执行文件中。您可以通过命令行开关、IDE 配置设置或什至 #pragma(具体取决于您的环境和编译器)告诉链接器执行此操作。

当您在 DLL 中链接时,您需要为链接器提供一些代码,以便在您调用其中一个 DLL 函数时调用。通常,这是使用与 .dll 同名的文件完成的,但它是一个 .lib。该 .lib 中的代码以与上述相同的方式链接到您的程序中,但是当您调用它时,它会加载 DLL(如果尚未加载),然后调用正确的函数。

还有其他方法可以处理 DLL 链接(例如,.def 文件或 .NET 中的 #using 语句),但这似乎是您在谈论的内容。


回应您的问题澄清:

问题在于 .lib 不是最终产品。它只是稍后在链接器将所有函数调用连接到函数地址时使用的目标代码的聚合。

另一方面,DLL 是最终产品,因此链接器要求所有函数和变量都连接到实际地址。

我说的有点不准确,但你明白了。

【讨论】:

  • 这并不完全准确。 DLL/Lib 样式链接比 .def 文件和 GetProcAddress 更快。无论如何我都赞成你,但只是为了迂腐,他们绝对不一样。例如,与 .def 文件相比,您可以使用 __declspec 链接成员函数等等。
  • 感谢您的解释。这清除了可执行项​​目中 Lib 和 DLL 链接的概念。对于将编译为lib 文件或dll 的框架,我仍然不完全理解为什么我不需要lib 的“附加依赖项”中的任何第三部分lib我的框架要编译,而我需要“附加依赖项”中的所有第 3 方 lib 文件,以便编译同一框架的 dll 版本。
  • 根据您的问题说明更新。
【解决方案2】:

一个静态库可以包含其他静态库,提供一个单独的库来链接

DLL 可以包含静态库,提供单个 DLL 进行链接。

依赖于其他 DLL 的 DLL 或静态库无法组合它们,因此您的可执行文件必须显式链接到那些其他 DLL。

【讨论】:

    【解决方案3】:

    当您链接到 LIB 时,它会将您实际使用的所有符号/函数添加到可执行文件中。您不使用的将不会被添加。当您链接到 dll 时 - 外部库中的所有代码都会被加载。如果这个额外的代码(你不使用的代码)依赖于更多的外部库,你也需要提供这些。

    一个例子:您想使用网络库中的 ip 类。 ip 类不依赖于其他库。网络库中的其他功能依赖于其他外部库。如果您将网络库链接为 LIB,您只需链接 ip 类 -> 您不需要其他库,因为其他代码不会被链接。当您使用 DLL 时,需要实例化 dll 中的所有代码 -> 因此您需要提供其他外部库。

    【讨论】:

      【解决方案4】:

      构建 DLL 更像是构建应用程序而不是库。构建应用程序和构建 DLL 之间的区别在于对可能调用的内容的了解。在应用程序中,所有未使用的符号都可以在构建中丢弃,但在 DLL 中,您不能删除未使用的符号 - 这将是所有符号...... 如果您能够调用 DLL 链接的所有符号,您会在静态库中发现相同的链接问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-09
        • 1970-01-01
        相关资源
        最近更新 更多