导入库如何工作,为什么 MinGW 不需要它们?
How do import libraries work and why doesn't MinGW need them?
我看了这个页面:深入了解Win32可移植可执行文件格式
它解释了链接器需要一个导入库,因为编译器无法区分普通函数调用和 API 函数调用。但他们也说__declspec(dllimport)将函数调用指定为API调用,因此链接器链接到__imp_[function-name]
。但是有了这个关键字,编译器应该知道这是对API函数的调用。
为什么链接器仍然需要导入库?编译器可以通过在函数名称前面加上__imp_
来将此符号标记为导入,并且可以调用函数指针(该指针尚是未解析的符号),链接器可以将此符号(因为它看到这是 API 调用)替换为 IAT 条目的地址。
为什么 MinGW-linker 可以直接使用"MinGW-DLL",而 Visual-Studio 链接器需要一个导入库?
当我阅读这篇文章时,还提出了其他一些问题。在与最终可执行文件的链接完成之前,"dlltool(或链接器)"(以创建导入库为准)如何知道 IAT 条目的位置?我认为 IAT 条目将在链接时与最终可执行文件一起构建。该帖子说,每个API调用在IAT表中都有一个固定的位置,更不用说将链接多少DLL。我无法想象如何能够做到这一点。
可以在没有导入库的情况下链接到 DLL,如 MinGW 清楚地演示的那样。因此,问题是为什么MSVC决定省略此功能。
原因主要是历史原因。
早在1983年,当Windows出现并设计DLL时,有许多来自不同供应商的工具链(编译器,链接器)。出去要求供应商实现对少数操作系统链接"DLL"的支持显然不是一种选择。
因此,他们决定编写一个工具来生成一个库,即使链接器完全不知道DLL,每个人和他们的狗也可以链接。
此外,导入库提供了一些 30 年前至关重要但现在几乎过时的功能。首先是按序数导入符号的能力——即.DLL可以选择根本不提供名称,只提供地址列表;序号是此列表中的索引。当 RAM 的数量受到严重限制时,变得有意义。
二是支持不同的名称重整方案。即使在 C 语言中也存在名称重整方案,例如 FooBar 可能会变得_FooBar@4(这取决于平台和调用约定)。DLL在每个受支持的平台上导出"FooBar"以实现一致性是完全有意义的(它使GetProcAddress()用户的生活更容易)。导入库实现了从_FooBar@4到FooBar的映射。
这是基于Raimond Chen的博客(1,2),他从一开始就参与了Windows开发。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么在全局范围内使用"extern int a"似乎不行?
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 为什么<iostream>依赖MinGW dll?
- 来自C#的mingw DLL:为什么我必须覆盖新建/删除?
- 为什么 mingw 4.4 说<random>需要 c++0x?
- 为什么我不能在 MinGW 中链接 64 位 .lib 文件?
- 为什么 CodeBlocks (13.12) 找不到 C:\MinGW\include?
- 导入库如何工作,为什么 MinGW 不需要它们?
- Qt5:此代码使用msvc2012编译正常,但使用MinGW编译时出现错误..为什么?
- 为什么使用MinGW时std::to_string()的运行速度是使用VS2012时的16倍
- 为什么我们必须在主函数中传递参数,而在Mingw中设置sdl
- 为什么MinGW将Win API函数定义为宏?
- 为什么需要Cygwin和MinGW ?
- 为什么在gcc版本的Mingw端口中有两个bin文件夹?
- 为什么 std::for_each 不使用 minGW 编译?
- 为什么 printf 在使用 MinGW-w64 时会生成一个额外的函数
- 为什么 MinGW 4.8 不将 ex.what() 视为虚拟
- 为什么round()被mingw知道,而不被visual studio编译器知道