使用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呢?
时间: 2024-11-01 23:50:46