.lib 和 .dll + .def 的区别

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

我有一些关于动态库和静态库的问题。 我知道dll是一个动态库,其图像被加载到内存中,所有进程都可以调用函数并使用它们。而.lib只是目标文件的存档,真的是这样吗?

我的俄语 MASM64 包(link)使用 .lib 库,我将其包含在 .asm 文件中,与系统 dll 的名称相同。 但是这些.lib文件不是目标文件的存档,它们告诉程序我可以调用dll中的哪些函数以及它们的地址? 我可以使用 dumpbin 转储来自 system32 中的 kernel32.dll 的导出,并为导出函数列表创建一个 .def 文件,然后使用 lib 实用程序创建一个 lib 文件。

还有一个关于 .inc 文件的问题,我知道它们只是 C/C++ 项目中的 .h 的模拟,那么这些条目之间有什么区别:

includelib "user32.lib"
extern __imp_ActivateKeyboardLayout:qword 
ActivateKeyboardLayout TEXTEQU <__imp_ActivateKeyboardLayout> 

写在我的包中的.inc文件中。 如果我自己在程序中编写它:

includelib "user32.lib"
ActivateKeyboardLayout PROTO

一切都会正常,有什么区别。我可以使用 dumpbin 为每个 .dll 创建 .lib 文件(如上所述),并在 .inc 文件中为所有函数编写 PROTO 吗?

assembly dll libraries masm masm64
1个回答
0
投票

请您Hans Passant 寻求提示。 在给出的示例中,ActivateKeyboardLayout 替换为 MessageBoxA 和 ExitProcess。

ExitProcess PROTO

事实证明,当我们使用 PROTO 指令声明一个函数时,编译器不知道它在哪里,所以当你在调试器中编译时,你可以看到以下内容:

enter image description here

对于函数ExitProcess,创建了一个所谓的Thunk,其本质是调用一个只有一个jmp的函数,它跳转到我们需要的函数。我假设这样做是因为,在构建过程中,链接器意识到 ExitProcess 函数实际上已导入,因此它跳转到源文件导入表中的指针。

extern __imp_MessageBoxA:qword

但是,对于 MessageBoxA 函数,我们通过为 MessageBoxA 函数指定 extern 关键字和 imp 前缀来告诉编译器它是第三方(导入)函数。调试器显示,调用 __imp_MessageBoxA 函数会导致直接调用 MessageBoxA,因为 __imp_MessageBoxA 只是导入表中指向 MessageBoxA 的指针。

upload_2023-3-24_13-20-6.png

一般来说,唯一的区别在于代码优化,因为它是双向的,但在第二种情况下,处理器少执行一条指令。

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