c++ - error - que significa undefined reference to winmain
referencia indefinida a `WinMain @ 16 '' (4)
Considere el siguiente programa de nivel de API de Windows:
#define NOMINMAX
#include <windows.h>
int main()
{
MessageBox( 0, "Blah blah...", "My Windows app!", MB_SETFOREGROUND );
}
Ahora construyamos usando la cadena de herramientas GNU (es decir, g ++), sin opciones especiales. Aquí gnuc
es solo un archivo por lotes que uso para eso. Solo proporciona opciones para hacer que g ++ sea más estándar:
C:/test> gnuc x.cpp C:/test> objdump -x a.exe | findstr /i "^subsystem" Subsystem 00000003 (Windows CUI) C:/test> _
Esto significa que el enlazador produjo de manera predeterminada un ejecutable del subsistema de consola . El valor del subsistema en el encabezado del archivo le dice a Windows qué servicios requiere el programa. En este caso, con el sistema de consola, el programa requiere una ventana de consola.
Esto también hace que el intérprete de comandos espere a que se complete el programa.
Ahora construyamos con el subsistema GUI , lo que significa que el programa no requiere una ventana de consola:
C:/test> gnuc x.cpp -mwindows C:/test> objdump -x a.exe | findstr /i "^subsystem" Subsystem 00000002 (Windows GUI) C:/test> _
Afortunadamente, eso está bien hasta ahora, aunque la bandera de -mwindows
está simplemente semi-documentada.
Construir sin esa bandera semi-documentada tendría que decirle al enlazador qué valor de subsistema desea, y algunas bibliotecas de importación de API de Windows tendrán que especificarse explícitamente en general:
C:/test> gnuc x.cpp -Wl,-subsystem,windows C:/test> objdump -x a.exe | findstr /i "^subsystem" Subsystem 00000002 (Windows GUI) C:/test> _
Eso funcionó bien, con la cadena de herramientas GNU.
Pero, ¿qué hay de la cadena de herramientas de Microsoft, es decir, Visual C ++?
Bueno, construir como un ejecutable del subsistema de consola funciona bien:
C:/test> msvc x.cpp user32.lib x.cpp C:/test> dumpbin /headers x.exe | find /i "subsystem" | find /i "Windows" 3 subsystem (Windows CUI) C:/test> _
Sin embargo, con la construcción de la cadena de herramientas de Microsoft como subsistema GUI no funciona por defecto:
C:/test> msvc x.cpp user32.lib /link /subsystem:windows x.cpp LIBCMT.lib(wincrt0.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartu p x.exe : fatal error LNK1120: 1 unresolved externals C:/test> _
Técnicamente, esto se debe a que el enlazador de Microsoft no es estándar por defecto para el subsistema GUI . De forma predeterminada, cuando el subsistema es GUI, el enlazador de Microsoft usa un punto de entrada de la biblioteca de tiempo de ejecución, la función donde se inicia la ejecución del código de máquina, llamada winMainCRTStartup
, que llama a WinMain
no estándar de WinMain
lugar de main
estándar.
No es gran cosa para arreglar eso, sin embargo.
Todo lo que tiene que hacer es decirle al enlazador de Microsoft qué punto de entrada usar, a saber, mainCRTStartup
, que llama a main
estándar:
C:/test> msvc x.cpp user32.lib /link /subsystem:windows /entry:mainCRTStartup x.cpp C:/test> dumpbin /headers x.exe | find /i "subsystem" | find /i "Windows" 2 subsystem (Windows GUI) C:/test> _
No hay problema, pero es muy tedioso. Y tan arcano y oculto que la mayoría de los programadores de Windows, que en su mayoría solo usan las herramientas no estándar de Microsoft, ni siquiera lo saben, y creen erróneamente que un programa de subsistema GUI de Windows "debe" tener WinMain
no estándar en lugar de estándar main
. De paso, con C ++ 0x, Microsoft tendrá un problema con esto, ya que el compilador debe entonces publicitar si es independiente o está alojado (cuando está alojado debe ser compatible con el estándar main
).
De todos modos, esa es la razón por la cual g ++ puede quejarse de la falta de WinMain
: es una función de arranque tonta y no estándar que las herramientas de Microsoft requieren por defecto para los programas del subsistema GUI.
Pero como puede ver arriba, g ++ no tiene problema con el estándar main
incluso para un programa de subsistema GUI.
Entonces, ¿Cuál podría ser el problema?
Bueno, probablemente te estás perdiendo un plato main
. ¡Y probablemente tampoco tenga WinMain
(apropiado)! Y luego g ++, después de haber buscado main
(no existe), y para WinMain
no estándar de WinMain
(no existe), informa que falta este último.
Prueba con una fuente vacía:
C:/test> type nul >y.cpp C:/test> gnuc y.cpp -mwindows c:/program files/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../libmingw32.a(main.o):main.c:(.text+0xd2): undefined referen ce to `WinMain@16'' collect2: ld returned 1 exit status C:/test> _
Cuando intento crear un programa usando Eclipse CDT
, obtengo lo siguiente:
/mingw/lib/libmingw32.a(main.o):main.c:(.text+0x106): referencia no definida a `WinMain @ 16
¿Porqué es eso? Y, ¿cómo puedo resolver este problema?
Intente guardar su archivo .c antes de compilar. Creo que su computadora está haciendo referencia a una ruta a un archivo sin información dentro de él.
--Tengo un problema similar cuando construyes proyectos C
Me encontré con este error al compilar mi aplicación con SDL. Esto fue causado por SDL definiendo su propia función principal en SDL_main.h. Para evitar SDL, defina la función principal que debe definirse una macro SDL_MAIN_HANDLED antes de incluir el encabezado SDL.h.
Para resumir la publicación anterior por Cheers y hth. - Alf, asegúrate de tener main()
o WinMain()
definido y g ++ debería hacer lo correcto.
Mi problema fue que main()
se definió por accidente dentro de un espacio de nombres.