undefined reference to `WinMain@16'

quand j'essaie de construire un programme en utilisant Eclipse CDT , j'obtiens ce qui suit:

/mingw/lib / libw32.principal.o):principal.C.(:texte+0x106): référence non définie à " WinMain@16

pourquoi? Et, comment puis-je résoudre ce problème?

95
demandé sur John Dibling 2011-03-10 15:41:32

4 réponses

Envisager la suite de l'API Windows au niveau du programme:

#define NOMINMAX
#include <windows.h>

int main()
{
    MessageBox( 0, "Blah blah...", "My Windows app!", MB_SETFOREGROUND );
}

maintenant, construisons-le en utilisant la chaîne D'outils GNU (i.e. g++), pas d'options spéciales. Ici gnuc est juste un fichier batch que j'utilise pour cela. Il ne fournit que des options pour rendre g++ Plus standard:

C:\test> gnuc x.cpp

C:\test> objdump -x a.exe | findstr /i "^subsystem"
Subsystem               00000003        (Windows CUI)

C:\test> _

cela signifie que le linker a produit par défaut un sous-système de console exécutable. La valeur du sous-système dans la l'en-tête de fichier indique à Windows les services dont le programme a besoin. Dans ce cas, avec le système de console, que le programme nécessite une fenêtre de console.

Cela fait aussi attendre l'interpréteur de commandes pour que le programme soit terminé.

construisons-le maintenant avec GUI subsystem , ce qui signifie Juste que le programme ne nécessite pas une fenêtre de console:

C:\test> gnuc x.cpp -mwindows

C:\test> objdump -x a.exe | findstr /i "^subsystem"
Subsystem               00000002        (Windows GUI)

C:\test> _

J'espère que c'est OK pour l'instant, bien que le Le drapeau -mwindows est à moitié documenté.

construction sans cet indicateur semi-documenté, il faudrait plus spécifiquement dire au linker quelle valeur de sous-système on désire, et certaines bibliothèques D'importation D'API Windows devront alors en général être spécifiées explicitement:

C:\test> gnuc x.cpp -Wl,-subsystem,windows

C:\test> objdump -x a.exe | findstr /i "^subsystem"
Subsystem               00000002        (Windows GUI)

C:\test> _

qui a bien fonctionné, avec la chaîne GNU.

mais qu'en est-il de la chaîne D'outils Microsoft, i.e. Visual C++?

Eh bien, construire comme une console sous-système exécutable fonctionne très 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> _

cependant, avec la construction de la chaîne D'outils de Microsoft comme sous-système GUI ne fonctionne pas par défaut:

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> _

techniquement, c'est parce que le linker de Microsoft n'est pas standard par défaut pour le sous-système GUI . Par défaut, lorsque le sous-système est GUI, alors linker de Microsoft utilise une bibliothèque d'exécution point d'entrée , la fonction là où commence l'exécution du code machine, appelé winMainCRTStartup , qui appelle le non standard de Microsoft WinMain au lieu du standard main .

pas grand-chose pour arranger ça, cependant.

Tout ce que vous avez à faire est de dire le linker de Microsoft quel point d'entrée à utiliser, à savoir mainCRTStartup , qui appelle la norme main :

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> _

Pas de problème, mais très fastidieux. Et si obscur et caché que la plupart des programmeurs Windows, qui la plupart du temps n'utilisent que les outils non standard-par défaut de Microsoft, ne savent même pas à ce sujet, et pensent à tort qu'un sous-système Windows GUI programme "doit" avoir non standard WinMain au lieu de la norme main . En passant, avec C++0x Microsoft aura un problème avec cela, puisque le compilateur doit alors annoncer s'il est autonome ou hébergé (lorsqu'il est hébergé, il doit prendre en charge la norme main ).

, c'est la raison pour laquelle g++ peut se plaindre de WinMain manquant: c'est une fonction de démarrage stupide non standard que les outils de Microsoft exigent par défaut pour les programmes de sous-système GUI.

mais comme vous pouvez le voir ci-dessus, g++ n'a aucun problème avec la norme main , même pour un sous-système GUI.

Alors, quel pourrait être le problème?

Eh bien, vous êtes probablement manquant a main . Et vous n'avez probablement pas non plus de WinMain ! Et puis g++, après avoir cherché main (pas de Tel), et WinMain (pas de tel) de Microsoft, signale que ce dernier est manquant.

test avec une source vide:

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> _
163
répondu Cheers and hth. - Alf 2014-12-30 02:01:16

pour résumer le message ci-dessus par Cheers et hth. - Alf, assurez-vous que vous avez défini main() ou WinMain() et g++ devrait faire la bonne chose.

mon problème était que main() était défini à l'intérieur d'un espace-nom par accident.

56
répondu Tim Ludwinski 2012-09-25 10:29:51

je rencontrais cette erreur lors de la compilation de mon application avec SDL. Cela a été causé par SDL définissant sa propre fonction principale dans SDL_main.H. Pour empêcher SDL de définir la fonction principale, une macro SDL_MAIN_HANDLED doit être définie avant SDL.h en-tête est inclus.

17
répondu X-Frox 2014-08-01 22:30:12

essayez de sauver votre .c fichier avant de l'immeuble. Je crois que votre ordinateur fait référence à un chemin vers un fichier sans aucune information à l'intérieur de lui.

--avait un problème similaire lors de la construction de projets C

1
répondu JabbaJava 2016-07-19 00:54:49