Win32 API调用引发访问冲突 我有一个简单的C++代码,我从DLL导出。

Win32 API调用引发访问冲突 我有一个简单的C++代码,我从DLL导出。,c++,winapi,encoding,C++,Winapi,Encoding,DWORD WINAPI MessageBoxThread(LPVOID lpParam) { MessageBox(0, L"Test", L"Test", 0); return 0; } 我这样称呼它 typedef DWORD(*MessageBoxThread)(LPVOID); int StartMessageBoxThread() { MessageBoxThread ShowMessageBox; HMODULE testModule = Load

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;
}
我在ShowMessageBox()行的KernelBase.dll中引发了一个异常,在写入内存位置时涉及访问冲突

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

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

typedef DWORD(*MessageBoxThread)(LPVOID);
原型与dll中的定义不匹配。默认情况下,这里的调用约定是
\uu cdecl
,而
WINAPI
\uu stdcall

typedef DWORD(WINAPI *MessageBoxThread)(LPVOID);

具体地说,在被调用端,由于约定是
\uu stdcall
(被调用方清除堆栈),因此函数从堆栈中弹出参数。在调用者端,它看到约定是
\uu cdecl
(调用者清除堆栈),它还从堆栈中弹出参数,最终损坏堆栈。

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

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

请尝试以下方法:

typedef-DWORD(WINAPI*MessageBoxThread)(LPVOID);
int StartMessageBoxThread()
{
HMODULE testModule=LoadLibrary(L“C:\\Users\\david\\COMServer.dll”);
if(测试模块)
{
MessageBoxThread ShowMessageBox=(MessageBoxThread)GetProcAddress(testModule,“MessageBoxThread”);
如果(显示消息框)
ShowMessageBox(空);
FreeLibrary(testModule);
}
返回0;
}

是否已禁用DLL导出的名称篡改?我怀疑您的
GetProcAddress
调用失败,但由于您没有检查错误,因此无法知道。您还应该检查
LoadLibrary
@JonathanPotter的返回值。我使用的是def文件,因此没有mangling@Mirko为了简洁起见,我把它去掉了,但是GetLastError()正在为两个调用返回0。请不要删除错误检查代码。我们也需要看到这一点。据我们所知,你做错了。事实上,如果你不检查返回值,你就做错了。