使用mingw編譯SDL工程時出現WinMain@16錯誤
使用SDL進行跨平台的物理仿真(可以在Windows/Linux/Mac上編譯),發現在使用mingw編譯時出現如下錯誤:
mkdir -p obj/Source/ output g++ -DSDL_BUILD -DWINDOWS_BUILD -ISource -I/usr/local/include obj/Source/game.c.o obj/Source/WindowsTime.c.o obj/Source/GLGraphics.c.o obj/Source/SDLMain.c.o obj/Source/BallData.c.o -o output/PhysicsTest -I/usr/local/include -L/usr/local/lib -lSDL -lSDLmain -lopengl32 -lglu32-lwinmm c:/mingw/bin/../lib/gcc/mingw32/4.5.0/../../../libmingw32.a(main.o):main.c:(.text+0xd2):對‘WinMain@16’未定義的引用 collect2: ld returned 1 exit status make: *** [output/PhysicsTest] Error 1
網上類似的錯誤也有很多:
undefined reference to `WinMain@16' collect2: ld returned 1 exit status
解釋是,找不到main或者WinMain函數。
那就非常詭異了,我不是已經鏈接了libSDLmain.a了嗎?
用nm查看一下:
$ nm /usr/local/lib/libSDLmain.a SDL_win32_main.o: 00000000 b .bss 00000000 d .data 00000000 r .rdata 00000000 N .stab 00000000 N .stabstr 00000000 t .text U _FreeLibrary@4 U _GetCommandLineA@0 U _GetModuleFileNameA@12 U _GetModuleHandleA@4 U _LoadLibraryA@4 000001f0 t _OutOfMemory 00000000 t _ParseCommandLine U _SDL_GetError U _SDL_Init U _SDL_Quit U _SDL_SetModuleHandle U _SDL_getenv U _SDL_main U _SDL_strlcat U _SDL_strlcpy 000001c0 t _ShowError 00000640 T _WinMain@16 U __imp____mb_cur_max U __imp___iob U __imp___pctype U __isctype U _atexit U _atoi 00000210 t _cleanup 00000220 t _cleanup_output 00000510 T _console_main U _exit U _fclose U _fgetc U _fopen U _fprintf U _freopen U _malloc 00000300 t _redirect_output U _remove U _setbuf U _setvbuf 00000120 b _stderrPath 00000000 b _stdioRedirectEnabled 00000010 b _stdoutPath U _strlen U _strrchr
00000640 T _WinMain@16,這個符號難道不是WinMain@16?
查看使用了main函數的文件,即
$ nm obj/Source/SDLMain.c.o 00000000 b .bss 00000000 d .data 00000000 i .drectve 00000000 r .rdata 00000000 t .text U _AddFrame 00000004 C _Buffer 00000004 C _CloseButtonPressed U _Game_Draw U _Game_Exit U _Game_Initialize U _Game_Work U _GetFrames U _GetTimeNow 00000004 C _MouseWheel 00000008 C _Orientation 0000011e T _PollEvents U _SDL_FreeSurface U _SDL_GL_SetAttribute U _SDL_GL_SwapBuffers U _SDL_GetMouseState U _SDL_GetVideoInfo U _SDL_Init U _SDL_PollEvent U _SDL_Quit U _SDL_SetVideoMode U _SDL_WM_SetCaption 00000256 T _SDL_main 00000004 C _ScreenHeight 00000004 C _ScreenScalar 00000004 C _ScreenWidth U _SetFramesPerSecond U _SubtractTime 000000d8 T _TouchChanged 000000ea T _TouchIsDown 000000ff T _TouchIsUp 00000004 C _TouchOldValue 00000008 C _TouchPos 00000004 C _TouchValue 00000114 T _Touching 00000000 T _Update_Input 00000004 C _WorkTime U _cos U _sin
_SDL_main這個符號是從何而來?
細心一想,發現最可疑的是,SDL的頭文件把main函數宏定義了,導致源文件編譯時不是main函數,而是被宏定義為SDL_main。加上
#undef main int main( int argc, char* argv[] ) {
編譯成功,此時再查看符號,發現_main出現了。
$ nm obj/Source/SDLMain.c.o 00000000 b .bss 00000000 d .data 00000000 i .drectve 00000000 r .rdata 00000000 t .text U _AddFrame 00000004 C _Buffer 00000004 C _CloseButtonPressed U _Game_Draw U _Game_Exit U _Game_Initialize U _Game_Work U _GetFrames U _GetTimeNow 00000004 C _MouseWheel 00000008 C _Orientation 0000011e T _PollEvents U _SDL_FreeSurface U _SDL_GL_SetAttribute U _SDL_GL_SwapBuffers U _SDL_GetMouseState U _SDL_GetVideoInfo U _SDL_Init U _SDL_PollEvent U _SDL_Quit U _SDL_SetVideoMode U _SDL_WM_SetCaption 00000004 C _ScreenHeight 00000004 C _ScreenScalar 00000004 C _ScreenWidth U _SetFramesPerSecond U _SubtractTime 000000d8 T _TouchChanged 000000ea T _TouchIsDown 000000ff T _TouchIsUp 00000004 C _TouchOldValue 00000008 C _TouchPos 00000004 C _TouchValue 00000114 T _Touching 00000000 T _Update_Input 00000004 C _WorkTime U ___main U _cos 00000256 T _main U _sin
一定要#undef main才可以嗎?
為什麼官方給的libSDLmain.a裏的_WinMain@16不是WinMain@16呢?
最後更新:2017-04-02 06:51:59