阅读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媒体库(一)