繁体   English   中英

导入库是如何工作的,为什么 MinGW 不需要它们?

[英]How do import libraries work and why doesn't MinGW need them?

我看了这个页面:深入了解 Win32 Portable Executable File Format

它解释了链接器需要导入库,因为编译器无法区分普通函数调用和 API 函数调用。 但他们也说 __declspec(dllimport) 将函数调用指定为 API 调用,因此链接器链接到__imp_[ function-name ] 但是有了这个关键字,编译器应该知道这是对 API 函数的调用。

为什么链接器还需要导入库? 编译器可以通过在函数名前__imp_来将此符号标记为导入,并且可以调用函数指针(这是一个尚未解析的符号),链接器可以替换这个符号(因为它看到这是一个 API 调用) IAT 条目的地址。

为什么 MinGW-linker 可以直接使用“MinGW-DLLs”而 Visual-Studio 链接器需要一个导入库?

当我阅读帖子时,还提出了一些其他问题。 在完成与最终可执行文件的链接之前,“dlltool(或链接器)”(以创建导入库的为准)如何知道 IAT 条目的位置? 我认为 IAT 条目将在链接时与最终可执行文件一起构建。 帖子说,每个API-Call在IAT表中都有一个固定的位置,不管有多少DLL会被链接。 我无法想象这是如何实现的。

正如 MinGW 清楚地展示的那样,可以在没有导入库的情况下链接到 DLL。 因此问题是为什么 MSVC 决定省略此功能。

原因主要是历史性的。

回到 1983 年,当 Windows 出现并设计 DLL 时,有许多来自不同供应商的工具链(编译器、链接器)。 出去要求供应商实现对少数操作系统链接“DLL”的支持显然不是一个选择。

因此,他们决定编写一个工具来生成每个人和他们的狗都可以链接的库,即使链接器完全不了解 DLL。

此外,导入库提供了一些 3 年前至关重要但现在已经过时的功能。 首先是按序导入符号的能力——即 DLL 可以选择完全不提供名称,只提供地址列表; 序数是此列表中的索引。 当 RAM 量严重受限时才有意义。

其次是支持不同的名称修改方案。 即使在 C 中也有名称修改方案,例如 FooBar 可能会变成 _FooBar@4(这取决于平台和调用约定)。 DLL 在每个支持的平台上导出“FooBar”以保持一致性是非常有意义的(并且它使 GetProcAddress() 用户的生活更轻松)。 导入库实现了_FooBar@4 到FooBar 的映射。

这是基于 Raimond Chen 的博客 (1 ,2 ),他从一开始就参与了 Windows 开发。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM