导入库如何工作?MinGW为什么不需要它们? [英] How do import libraries work and why doesn't MinGW need them?

查看:78
本文介绍了导入库如何工作?MinGW为什么不需要它们?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看了以下页面:深入了解Win32 Portable可执行文件格式

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

It explains that the linker needs an import library because the compiler can't distinguish between normal function calls and API-function calls. But they say also that __declspec(dllimport) specifies a function call to be an API-Call so the linker links against __imp_[function-name]. But with this keyword the compiler should know that this is a call to an API-Function.

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

Why does the linker still need an import library? The compiler could mark this symbol as imported by prepending __imp_ to the function name and could make a call to a function pointer (which is an unresolved symbol yet) and the linker could replace this symbol (because it sees that this an API call) with the IAT entry's address.

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

And why can the MinGW-linker use "MinGW-DLLs" directly but the Visual-Studio linker needs an import library?

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

As I read the post some other questions were also raised. How does the "dlltool (or linker)" (whichever creates the import library) know the location of an IAT entry before linkage with the final executable has been done? I thought the IAT entries would be constructed at link-time with the final executable. The post said, that every API-Call has a fixed position in the IAT table, never-mind how many DLLs will be linked. I cannot imagine how that could be achieved.

推荐答案

正如MinGW清楚地表明的那样,可以在没有导入库的情况下链接到DLL.因此,问题在于为什么MSVC决定忽略此功能.

It is possible to link to DLL without an import library as MinGW clearly demonstrates. Hence the question is why MSVC decided to omit this feature.

原因主要是历史原因.

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

Back then in 1983 when Windows came around and DLLs were designed there were many toolchains (compilers, linkers) from different vendors. Going out asking the vendors to implement support for linking "DLLs" for a minority OS was clearly not an option.

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

So they made a decision to write a tool to generate a library everyone and their dog could link against even if a linker had absolutely no idea about DLLs.

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

Besides, import libraries offer some features that were vital 3 decades ago but are next to obsolete now. First is the ability to import a symbol by ordinal — i.e. DLL has an option to offer no names at all only a list of addresses; the ordinal is an index in this list. Made sence when the amount of RAM was severely limited.

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

Second is the support for different name mangling schemes. Even in C there is a name mangling scheme, for instance FooBar may become _FooBar@4 (it depends on the platform and the calling convention). It made perfect sense for a DLL to export "FooBar" on every supported platform for consistency (and it makes the life of GetProcAddress() user easier). Import library implements the mapping from _FooBar@4 to FooBar.

这基于博客( 1 ,<参与Windows开发的人Raimond Chen的a href ="https://devblogs.microsoft.com/oldnewthing/20091012-00/?p=16413" rel ="nofollow noreferrer"> 2 )从一开始.

This is based on the blog (1, 2) of Raimond Chen, the man who was involved in Windows development from the very beginning.

这篇关于导入库如何工作?MinGW为什么不需要它们?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆