引发访问冲突的 Win32 API 调用



我有一段简单的C++代码,我正在从DLL导出。

DWORD WINAPI MessageBoxThread(LPVOID lpParam)
{
MessageBox(0, L"Test", L"Test", 0);
return 0;
}

这是我怎么称呼它的

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;
}

我在 KernelBase 中抛出了一个异常.dll在 ShowMessageBox(( 行上,涉及写入内存位置时的访问冲突。

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

我可以调试并单步执行我的 DLL,我看到我的函数的地址,所以我看不出调用函数的代码有什么问题。

typedef DWORD(*MessageBoxThread)(LPVOID);

原型与 dll 中的定义不匹配。默认情况下,此处的调用约定是__cdecl,而WINAPI__stdcall

typedef DWORD(WINAPI *MessageBoxThread)(LPVOID);

具体来说,在被调用端,由于约定是__stdcall的(被调用方清除堆栈(,该函数会从堆栈中弹出参数。在调用方端,它看到约定__cdecl(调用方清除堆栈(,并且它还从堆栈中弹出参数,最终损坏堆栈。

StartMessageBoxThread()代码中,MessageBoxThread声明不正确。具体来说,它缺少调用约定,因此它使用编译器的默认约定,该约定通常是__cdecl而不是__stdcall(WINAPI映射到的内容(。调用约定不匹配是崩溃、调用堆栈损坏等的常见原因。

此外,代码根本没有错误检查。

试试这个:

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

最新更新