閱讀602 返回首頁    go 阿裏雲 go 技術社區[雲棲]


使用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

  上一篇:go Flex borderSkin繪自定義寬度邊框的實例
  下一篇:go 在32位的Ubuntu 11.04中為Android NDK r6編譯FFmpeg0.8.1版-Android中使用FFmpeg媒體庫(一)