编译 dll 项目时生成的 .lib 文件有啥用处,我可以将它用于静态链接吗? [复制]

Posted

技术标签:

【中文标题】编译 dll 项目时生成的 .lib 文件有啥用处,我可以将它用于静态链接吗? [复制]【英文标题】:What is usefulness of .lib file generated while compiling the dll projects, can i use it for static linking? [duplicate]编译 dll 项目时生成的 .lib 文件有什么用处,我可以将它用于静态链接吗? [复制] 【发布时间】:2017-02-01 06:52:20 【问题描述】:

想问问编译dll项目时生成的.lib文件有什么用。

当我们编译我们的项目时,会生成以下文件: .dll .exp .lib .pdb

现在我们还有 .lib 文件,我们可以使用这个文件将它静态链接到任何其他项目吗?如果不是,那么生成这个 .lib 文件有什么用。

【问题讨论】:

您可能会发现this question 信息丰富。 嗨,格雷,那里提出的问题的标题完全不同,任何试图为我提出的类似问题找到答案的人都不会去搜索导入库的工作原理,你不能复制它,在至少为了其他用户发现类似问题 【参考方案1】:

.dll 一起生成的.lib 称为“导入库”,它允许您使用包括它们的头文件在内的dll 函数,就好像它们在您的可执行文件中静态链接一样。它确保当链接器必须修复引用到目标文件中的 dll 函数地址时,它可以在导入库中找到它们。在导入库中找到的这些函数实际上是存根,它从导入地址表中检索加载的 dll 中相应函数的实际地址并直接跳转到它(传统上;现在链接器中有一些智能可以避免这种双重跳)。

反过来,导入库包含用于链接器的特殊指令,指示它在可执行文件的导入表中生成相关条目,然后在加载时由加载器(“动态链接器”,在 Unix 术语中)。这可以确保在调用可执行文件的入口点之前,加载引用的 dll,并且 IAT 包含引用函数的正确地址。

请注意,所有这些主要是为了方便您调用 dll 函数,就好像它们静态链接到您的可执行文件一样。如果您显式处理动态加载/函数地址检索(使用 LoadLibrary 和 GetProcAddress),则严格需要 .lib 文件;将所有这些东西委托给链接器和加载器会更方便。

【讨论】:

【参考方案2】:

.lib 共享库不用于静态链接,它用于让链接器了解隐藏在 .dll 文件中的内容。将其视为您提供给链接器的头文件,以确保它知道属于 .dll 以及您需要的所有函数。问自己一个问题:如果没有 .lib,您将如何使用生成的 .dll 文件? LoadLibrary 不计算在内 - 它有复杂性(类方法?重整?)并像 opencv_ffmpeg.dll 一样产生不确定性:它不能存在于 PATH 中,并且 opencv_video 链接程序仍将运行,但不会告诉我们任何事情,没有它就不会播放视频 - 没有明确的错误消息。此外,此方法是特定于平台的。

另一方面,.lib 静态库包含一个成熟的目标文件,它直接包含在可执行文件中。

基本思想 - 无论是静态库还是共享库,您仍然应该以几乎相同的方式链接它们 - 但是,如果它是共享库,您的程序将不会在不包含相应的 .dll 的情况下运行。

【讨论】:

实际上,LoadLibrary 是最灵活的方法 - 其他一切都是根据它构建的 - 当您链接导入库时,您将 LoadLibrary/GetProcAddress 委托给领导者,并要求编译器编写通过 IAT 间接调用而不是直接函数调用,但底层管道是相同的。 @MatteoItalia - 好吧,同意。另一方面,汇编程序在性能和潜力方面更加灵活。尽管如此,我们还是使用 C++ 进行编码。 @MatteoItalia 我的意思是一切都是建立在某些东西上的,但是如果肯定有更好的方法(因为它确实在这种情况下暴露了编译时的错误,并且不需要程序员知道完整的函数名被重整毒害,你可以在其中打错字并永远调试它),为什么要使用更难的? 我并不是说您应该始终明确地使用 LoadLibrary - 实际上,通常您不会,由于您所说的原因,使用导入库要方便得多;我的意思是说LoadLibrary 有更多限制是不正确的,而事实上恰恰相反——它是与特定用例相关的导入库链接(并且很好地解决了它),LoadLibrary/GetProcAddress 是更通用的工具。 @MatteoItalia 修复了答案。这就是我的意思——确切地说,更多的是并发症,而不是限制

以上是关于编译 dll 项目时生成的 .lib 文件有啥用处,我可以将它用于静态链接吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

编译后的dll,xml,pdb分别是什么内容,各有什么用处?

编译后的dll,xml,pdb分别是什么内容,各有什么用处?

Visual Studio 2017 动态链接库(DLL /LIB) 静态链接库(LIB)的思考

Visual Studio中怎么生成动态链接库的lib文件

.h头文件 .lib库文件 .dll动态链接库文件关系

一个C++项目, 已有一些静态库(.lib)和所有的函数声明(.h),怎么生成一个动态库(dll)