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

问题描述 投票:10回答:1

我看了此页面:An In-Depth Look into the Win32 Portable Executable File Format

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

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

为什么MinGW链接器可以直接使用“ MinGW-DLL”,但是Visual-Studio链接器需要导入库?

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

c++ c windows dll linker
1个回答
13
投票
如MinGW清楚显示的那样,无需导入库就可以链接到DLL。因此,问题在于为什么MSVC决定忽略此功能。

原因主要是历史性的。

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

因此,他们决定编写一种工具来生成每个人都可以使用的库,即使链接器对DLL完全一无所知,他们的狗也可以对其进行链接。

此外,导入库提供了3年前至关重要的功能,但现在已经过时了。首先是可以按序导入符号的功能,即DLL可以选择不提供任何名称,而只提供地址列表。序数是此列表中的索引。在严重限制RAM数量的情况下显示。

第二是对不同名称处理方案的支持。即使在C语言中,也存在名称处理方案,例如FooBar可能会变成_FooBar @ 4(取决于平台和调用约定)。对于DLL而言,在每个受支持的平台上导出“ FooBar”以保持一致性是非常有意义的(这使GetProcAddress()用户的生活更加轻松)。导入库实现了从_FooBar @ 4到FooBar的映射。

这是基于Raimond Chen的博客(12),该人从一开始就参与Windows开发。

© www.soinside.com 2019 - 2024. All rights reserved.