我有一些关于动态和静态库的问题。我知道dll是一个动态库,它的图像被加载到内存中,所有进程都可以调用函数并使用它们。而.lib只是一个目标文件的存档,真的是这样吗?
我的俄罗斯MASM 64包(link)使用.lib库,我将其包含在我的.asm文件中,与系统dll同名。但这些.lib文件不是目标文件的存档,它们告诉程序我可以调用dll中的哪些函数以及它们的地址?我可以使用dumpbin转储从kernel32.dll导出的内容,它在我的system32中,并为导出的函数列表创建一个.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吗?
1条答案
按热度按时间hvvq6cgz1#
感谢你的提示。在给出的例子中,用MessageBoxA和ExitProcess替换ActivateKeyboardLayout。
事实证明,当我们使用PROTO指令声明一个函数时,编译器不知道它在哪里,所以当你在调试器中编译时,你可以看到以下内容:
对于函数ExitProcess,创建了一个所谓的Thunk,其本质是调用一个仅由一个jmp组成的函数,该函数跳转到我们需要的函数。我假设这样做是因为,在构建过程中,链接器意识到ExitProcess函数实际上是导入的,因此它跳转到源文件导入表中的指针。
然而,在MessageBoxA函数的情况下,我们通过为MessageBoxA函数指定extern关键字和imp前缀来告诉编译器它是第三方(导入)函数。调试器显示调用__imp_MessageBoxA函数会导致直接调用MessageBoxA,因为__imp_MessageBoxA只是导入表中MessageBoxA的指针。
一般来说,唯一的区别是代码优化,因为它以两种方式工作,但在第二种情况下,处理器少执行一条指令。