32位TDM MinGW用wmain遇WinMain@16未定义引用问题求助
32位TDM MinGW下wmain()引发WinMain@16未定义链接错误的解决办法
问题描述
将Windows程序迁移至Unicode版本时,将入口函数从main()改为wmain()后,32位TDM MinGW(g++ 10.3.0)编译通过但链接报错,错误输出如下:
c:\tdm32\bin\g++ -Wall -s -O3 -c -Weffc++ -Wno-write-strings -DUNICODE -D_UNICODE media_list.cpp c:\tdm32\bin\g++ media_list.o common.o qualify.o ext_lookup.o file_fmts.o conio_min.o MediaInfoDll.o -s -O3 -dUNICODE -d_UNICODE -o MediaList.exe -lshlwapi c:/tdm32/bin/../lib/gcc/mingw32/10.3.0/../../../../mingw32/bin/ld.exe: c:/tdm32/bin/../lib/gcc/mingw32/10.3.0/../../../libmingw32.a(main.o):(.text.startup+0xc0): undefined reference to `WinMain@16' collect2.exe: error: ld returned 1 exit status make: *** [MediaList.exe] Error 1
64位TDM MinGW可通过-municode链接选项解决该问题,但32位版本不支持此选项。
可行解决方案
1. 手动实现WinMain入口转发至wmain
添加一个WinMain函数,将系统传入的命令行参数转换为Unicode格式后转发给wmain:
#include <windows.h> #include <shellapi.h> // 声明你的wmain函数 int wmain(int argc, wchar_t* argv[]); int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdLine, int showCmd) { int argc; wchar_t** argv = CommandLineToArgvW(GetCommandLineW(), &argc); if (!argv) return 1; int retVal = wmain(argc, argv); LocalFree(argv); return retVal; }
注意:编译时需链接shell32库,在链接命令末尾添加-lshell32。
2. 定义_MINGW_WMAIN编译宏
在编译阶段添加-D_MINGW_WMAIN宏,让MinGW的启动代码识别wmain作为程序入口。修改编译命令如下:
c:\tdm32\bin\g++ -Wall -s -O3 -c -Weffc++ -Wno-write-strings -DUNICODE -D_UNICODE -D_MINGW_WMAIN media_list.cpp
链接阶段保持原有命令即可,该宏会覆盖默认的入口点查找逻辑,直接寻找wmain。
3. 直接使用WinMain处理Unicode参数
放弃wmain,直接以WinMain作为入口,通过Windows API获取并解析Unicode命令行参数:
#include <windows.h> #include <shellapi.h> int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdLine, int showCmd) { int argc; wchar_t** argv = CommandLineToArgvW(GetCommandLineW(), &argc); if (!argv) { MessageBoxW(nullptr, L"命令行参数解析失败", L"错误", MB_ICONERROR); return 1; } // 在此处编写原wmain中的业务逻辑,使用argc和argv LocalFree(argv); return 0; }
此方法同样需要链接shell32库,链接命令添加-lshell32。
内容的提问来源于stack exchange,提问作者Gorlash
相关产品推荐
相关产品推荐

