程序静态链接到库,但仍需要dll才能运行。

26

涉及到链接时有些事情我不是很明白...我正在使用第三方库GEOS来编写程序。这个程序依赖于geos.lib,但仍然需要geos.dll才能运行。

我读了这个问题,我认为我理解了静态库和动态库之间的区别。但我不明白的是,为什么当我静态链接一个库时,仍然需要一个dll。

5个回答

35

在Windows上有三种类型的库:

  • 对象库(*.lib)
  • 导入库(*.lib)
  • 动态链接库(*.dll)

对象库是静态链接的。它们包含了由库抽象的代码的完整对象定义。

导入库是对象库的一种特殊形式。不像包含代码,它们包含了链接器所需信息,最终将可执行文件映射到动态链接库。

动态链接库和对象库一样为您的程序提供代码。然而,这些代码在运行时加载而不是编译到您的exe中。

您并不总是需要链接一个导入库。相反,您可以调用LoadLibrary()并通过名称或序数查找API入口点。(您始终需要告诉代码您想要进入哪个DLL以及该DLL的API在哪里。)

此处的其他评论是正确的,即没有办法将DLL转换为静态库而不重新编译库的代码 - 这是一种不同类型的输出。


5
《连接器初学者指南》(http://www.lurklurk.org/linkers/linkers.html)是一篇关于连接的优秀文章。我在本周研究这个确切的问题时发现了它。 - Pressacco

26

它不是静态链接的。.lib只是一个存根库,将.dll绑定在Windows上。也就是说,你在编译时链接.lib,然后在运行时它会查找.dll。


难道没有任何选项可以允许静态链接特定的.dll文件中的代码吗? - Bartek Banachewicz
1
我认为你必须编译库以进行静态链接,我不确定在编译后能否将dll转换为静态链接库。 - Andrew Tomazos
@Andrew,dll文件总是带有.lib文件吗?我怎么知道当.lib文件不足以满足需求时需要提供dll文件呢? - undu
1
@undu:在Windows上,是的,你总是需要链接一个.lib文件来动态链接一个dll。dll供应商会在某个地方为你包含这个文件。你的意思是如何知道.lib是静态库吗?我想你可以在Visual Studio中检查这些属性。 - Andrew Tomazos
如何知道库是对象库还是导入库的相关问题:https://dev59.com/aWw15IYBdhLWcg3wxurL - Zitrax
显示剩余2条评论

3
如果.lib文件是由Visual Studio创建的,则需要检查项目属性-链接器-输入-模块定义文件的值。如果不为空,则link.exe将创建桩库而不是静态库,即使项目属性-常规-配置类型为“静态库(.lib)”。请注意保留HTML标签。

0

你肯定是在链接一个动态库。 仅仅因为链接器需要 .lib 文件并不意味着你正在链接一个静态库。


0
只有当这是静态库文件时,您才能静态链接 lib 文件。因此,您需要先将 dll 的项目转换为静态库,构建它,然后使用构建产品,该产品将是一个静态的 .lib 文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接