我正在尝试使用 mingw32 从 this Github 存储库编译 .cpp 文件。特别是,我可以编译包含代码的 .cpp 文件:
#include <windows.h>
extern "C" __declspec(dllexport)
DWORD WINAPI MessageBoxThread(LPVOID lpParam) {
MessageBox(NULL, "Hello world!", "Hello World!", NULL);
return 0;
}
extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
CreateThread(NULL, NULL, MessageBoxThread, NULL, NULL, NULL);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
使用 mingw32-g++ 和命令:
i686-w64-mingw32-g++ hello-world.cpp -o hello-world.dll -shared
编译时没有错误。当我尝试使用
rundll32.exe hello-world.dll,MessageBoxThread
运行 dll 时,它不起作用,即使导出函数确实存在(使用“dllexp.exe”可见)。当我通过 Visual Studio 中的解决方案获取相同的代码并编译它时,生成的 dll 二进制文件按预期工作。
为什么上述代码使用 mingw32-g++ 不能产生与 Visual Studio 相同的所需功能?如何修改上述源代码以使用 mingw32-g++ 进行编译?
使用 DLL 时最常见的问题是调用约定。在您的代码中,您使用了
__declspec(
dllexport) 属性,该属性通常与 Visual Studio 一起使用,但它不一定是 MinGW 的正确属性。 MinGW 通常使用 __attribute__((stdcall))
属性来指定调用约定。尝试按如下方式更改函数声明:
extern "C" __attribute__((stdcall)) DWORD WINAPI MessageBoxThread(LPVOID lpParam) {
在 DLL_PROCESS_ATTACH 中创建新线程的方式取决于平台。在 Visual Studio 中,它可能会起作用,因为它使用与 MinGW 不同的线程创建机制。为了确保代码与两者兼容,您可以直接使用 Windows API CreateThread。
case DLL_PROCESS_ATTACH:
CreateThread(NULL, 0, MessageBoxThread, NULL, 0, NULL);
break;