导入库是如何工作的? [复制]

Posted

技术标签:

【中文标题】导入库是如何工作的? [复制]【英文标题】:How import libraries work exactly? [duplicate] 【发布时间】:2017-02-17 10:18:08 【问题描述】:

我听说导入库有“存根”,所以可执行文件知道我们想要哪个 dll 和函数。现在我的问题是:那些存根是什么?他们看起来怎么样?可执行文件如何将指针设置到 DLL 中的正确位置?它怎么知道我们是在谈论普通库还是导入库,因为它们都是 .lib 文件?

【问题讨论】:

另见msdn.microsoft.com/en-us/magazine/bb985992.aspx 可执行文件不知道这些。它是链接器,它发出适当的代码。 【参考方案1】:

MSVC 链接器不直接链接到 DLL,它只能链接到静态库 (.lib)。

非常粗略地说,导入库是一个普通的静态库,它为每个 DLL 导出函数都有一个存根函数。

例如,如果一个DLL有一个函数void func1()并导出func1,那么相应的导入库将包含一个存根函数void __imp__func1() __asm jmp dword ptr func1;

在运行时,“跳转”将从导入表中获取func1 的地址。这就是需要存根的原因。

您的应用程序中的声明void __declspec(dllimport) func1(); 实际上将引用__imp__func1()

您可以完全绕过整个机制,并在运行时调用LoadLibraryGetProcAddress 来获取func1 的地址。它会产生同样的效果。

【讨论】:

【参考方案2】:

这取决于您使用的编译器(链接器)和平台。

即在 Windows 操作系统上,共享库通常是 .DLL 文件, 如果你想链接到它(除了动态加载它并在运行时解析它的符号),你需要相应的 .LIB 文件,即存根库。

基本上,存根库是一个静态库,它将 DLL 导出的所有符号(使用 __declspec(dllexport))重新映射到存根中存在的符号,并且可以使用 __declspec(dllimport) 在程序中找到并静态链接这些符号.

【讨论】:

那么 __declspec(dllexport) 是 Windows API 中的函数还是 Visual Studio 中的指令? @Daniel Nyman:'__declspec' 是一个关键字(据我所知,特定于 Visual Studio),'dllexport' 和 'dllimport' 是该关键字的属性。查看更多信息:msdn.microsoft.com/en-us/library/3y1sfaz2.aspx __declspec 是一个关键字,用于分配 Microsoft 特定的存储类属​​性。

以上是关于导入库是如何工作的? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何通过WebApi构建生产入库单?

在android开发中,不能导入开源的库是啥原因

如何快速将excel数据导入金蝶k3系统的单据中

java实现导入Excel数据入库

java实现导入Excel数据入库

如何让库从同一个包中导入库?