8

在 Windows 环境下,

当我尝试将 DLL显式链接到我的程序时(使用 LoadLibrary),

  • 首先,我需要根据 DLL 中的每个函数签名来定义函数指针。
  • 然后使用“GetProcAddress”获取函数地址并将它们分配给这些指针。

当我尝试将 DLL隐式链接到我的程序时(使用头文件)

  • 首先它需要相关的头文件来获取函数签名。
  • 然后它需要Lib使用 DLL 生成的相关文件。

    我的问题是

    1. 为什么隐式链接也需要一个Lib文件?
    2. 它需要从“Lib”文件中检索哪些无法从DLLor中获取的信息Header file
    3. 如果有问题 2 的内容,那么在显式加载时如何检索信息?

我已经解决了这个问题。但我无法理解任何有价值的理由。拜托,有人可以帮助用简单的术语解释一下。谢谢你。

4

2 回答 2

3

为什么隐式链接也需要 Lib 文件。

.libs 中有 dll 的导入信息,您可以使用dumpbinWindows/Visual Studio SDK 中包含的命令查看信息。

这是ws2_32.lib里面recv的链接信息例如:

Version      : 0
Machine      : 14C (x86)
TimeDateStamp: 4907F6ED Wed Oct 29 01:38:53 2008
SizeOfData   : 00000014
DLL name     : WS2_32.dll
Symbol name  : _recv@16
Type         : code
Name type    : ordinal
Ordinal      : 16

您可以检查 ws2_32.dll 中是否存在序号和名称(检查现在是否显示要导入 DLL)。

它需要从无法从 DLL 或头文件中获取的“Lib”文件中检索哪些信息

在头文件中,没有从何处提取导入的信息,因此在编译时将它们标记为导入 (__imp__name),当它与 .lib 链接时,它会解析名称:

  • 如果它在 .lib 内,它只是链接到它。
  • 但是,如果有关于外部引用 (DLL) 的信息,它将在导入表中构造导入,以便动态加载。

如果有问题 2 的内容,则在显式加载时如何检索这些信息。

如果显式加载是指 LoadLibrary,那么您是在运行时而不是在链接时告诉它。因此,PE 加载器将在 PATH 中搜索 DLL 并动态加载它。然后你有其他函数来获取导出的函数地址。

如果您有不明白的地方可以问我,如果您想更好地理解这一点,请尝试使用 dumpbin 并阅读有关 PE 的内容。

于 2013-07-24T04:58:42.753 回答
2

隐式链接时,函数声明指定要在程序中使用的名称、原型和调用约定。但需要更多信息。具体来说:

  1. 该函数在 DLL 外部实现的事实。
  2. 该 DLL 的名称。
  3. 函数的导出名称。这是用于从 DLL 中导出函数的名称,可能与导入时使用的名称不同。

一些语言设计者选择使用语言扩展来提供这些信息。例如德尔福采取了这条路线。隐式链接完全在没有 .lib 文件的代码中指定。另一方面,C 和 C++ 的约定是使用 .lib 文件来指定缺失的信息。

于 2014-08-13T07:15:44.333 回答