如何在 x86 上使用 .def 文件为 kernel32.dll 创建导入库?

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

我有一个不依赖CRT或windows sdk的小项目。为了链接到 kernel32.dll,我创建了一个最小的 .def 文件,其中仅包含我需要的几个函数:

LIBRARY kernel32.dll
EXPORTS
ExitProcess

然后我在构建过程中使用以下命令创建 .lib:

lib /DEF:kernel32.def /OUT:kernel32.lib /MACHINE:x86

我的代码中函数的声明如下所示:

#ifdef __cplusplus
extern "C"{
#endif
__declspec(dllimport) __declspec(noreturn) void __stdcall ExitProcess(UINT uExitCode);
#ifdef __cplusplus
}
#endif

在编译和链接 x64 时效果非常好(使用 /MACHINE:x64 创建的库),但是当我切换到 x86 时,我收到

__imp__ExitProcess@4
的未解析符号错误。

通过将 def 文件中的导出名称更改为

ExitProcesss@4
可以解决此链接器错误,但在运行程序时,会出现错误,提示
The procedure entry point 'ExitProcess@4' was not found in MyProgram.exe

如果我从 Windows sdk 链接到 kernel32.lib,一切都会正常。所以问题一定是在创建 def 文件和创建导入库之间。

我能找到的唯一参考是 mingw 的 .def 文件,它看起来与我的完全一样:https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-crt/lib32/kernel32.def 尽管由于该文件可能由 mingw 工具使用,但它的输出可能与 msvc 中的 lib 工具不同。

visual-c++ x86 dllimport kernel32 import-libraries
1个回答
0
投票

只有 def 文件不够,以防此处出现 x86

if 在 def 中将是名称

ExitProcess
- 在 lib 中也将是
__imp_ExitProcess
。但客户等待
__imp__ExitProcess@4
。所以你在构建时失败了。

如果你设置了

ExitProcess@4
你的PE将从
kernel32.dll
导入_ExitProcess@4并在运行时失败

此处的解决方案将 c/cpp/asm 文件与 def

结合使用

最小解决方案:首先使用这样的kernel32.asm

.686
.model flat

.code

_ExitProcess@4 proc
_ExitProcess@4 endp

end

并将其编译为

ml /c /Cp kernel32.asm

def 就是这样

EXPORTS
ExitProcess

最后使用下一个命令

link /DLL /NOENTRY /MACHINE:x86 /def:kernel32.def kernel32.obj 

在此之后,您得到了正确的kernel32.libkernel32.dllkernel32.exp易于删除)

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