我正在尝试通过创建一个指定我需要使用的函数的 .def 文件来将非托管 DLL 中的函数导入 C 项目。我正在练习MessageBoxA
从user32.dll
. 它是一个 stdcall 函数,与其他 WinAPI 函数一样。这是我创建 .def 文件的方法:
LIBRARY user32.dll
EXPORTS
_MessageBoxA@16
然后我像这样从中创建一个 .lib:lib /def:"C:\Path\to\def\user32.def" /
out:"C:\path\to\project\user32-mb.lib"
它成功地创建了user32-mb.lib
和user32-mb.exp
. 然后,在我的 C 项目中,我执行以下操作:
#pragma comment(lib, "user32-mb.lib")
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
EXTERNC __declspec(dllexport) int __stdcall MessageBoxA(void *hWnd, char *lpText, char *lpCaption, int uType);
void main(){
MessageBoxA(0, "MessageBox test", "MessageBox test", 0x00000030L);
}
但是,在链接时,它会给出以下错误:
error LNK2019: unresolved external symbol _MessageBoxA@16 referenced in function _main
但是,当我将 .def 中的声明更改为:
LIBRARY user32.dll
EXPORTS
MessageBoxA
并将我的 C 代码中的函数原型更改cdecl
为stdcall
:
EXTERNC __declspec(dllexport) int __cdecl MessageBoxA(void *hWnd, char *lpText, char *lpCaption, int uType);
消息框实际上出现了,但在关闭时,它会抛出一个错误:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
这表明调用它cdecl
也是一个坏主意,因为它stdcall
毕竟需要。
问题是,我应该在 .def 文件或我的项目中进行哪些更改以避免这两种错误并stdcall
正确导入和调用函数?