Win32 API调用引发访问冲突

dav*_*vid -1 c++ winapi encoding

我有一个从DLL导出的简单的C ++代码。

DWORD WINAPI MessageBoxThread(LPVOID lpParam)
{
    MessageBox(0, L"Test", L"Test", 0);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是我的称呼方式

typedef DWORD(*MessageBoxThread)(LPVOID);
int StartMessageBoxThread() {
    MessageBoxThread ShowMessageBox;
    HMODULE testModule = LoadLibrary(L"C:\\Users\\david\\COMServer.dll");
    ShowMessageBox = (MessageBoxThread)GetProcAddress(testModule, "MessageBoxThread");
    ShowMessageBox(NULL);
    FreeLibrary(testModule);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我在ShowMessageBox()行的KernelBase.dll中引发了异常,该异常在写入内存位置时涉及访问冲突。

我不明白我在做什么错。两个Visual Studio项目都设置为Unicode,并且我知道使用L前缀表示宽字符串。

我可以调试并逐步进入DLL,看到函数的地址,因此调用函数的代码看不到任何错误。

Gau*_*gal 5

typedef DWORD(*MessageBoxThread)(LPVOID);
Run Code Online (Sandbox Code Playgroud)

原型与dll中的定义不匹配。默认情况下,在这里调用约定__cdecl,而WINAPIIS__stdcall

typedef DWORD(WINAPI *MessageBoxThread)(LPVOID);
Run Code Online (Sandbox Code Playgroud)

具体来说,在被调用端,由于约定为__stdcall(被调用方清除堆栈),因此该函数将参数弹出堆栈。在调用者端,它看到约定是__cdecl(调用者清除了堆栈),并且还从堆栈中弹出了参数,最终破坏了堆栈。