Considérez le programme de niveau API Windows suivant:
#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 (ie g ++), pas d'options spéciales. Voici gnuc
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 "^ sous-système"
Sous-système 00000003 (Windows CUI)
C: \ test> _
Cela signifie que l'éditeur de liens a produit par défaut un exécutable de sous-système de console . La valeur du sous-système dans l'en-tête du 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 oblige également l'interpréteur de commandes à attendre la fin du programme.
Maintenant, construisons-le avec le sous - système GUI , ce qui signifie simplement que le programme ne nécessite pas de fenêtre de console:
C: \ test> gnuc x.cpp -mwindows
C: \ test> objdump -x a.exe | findstr / i "^ sous-système"
Sous-système 00000002 (interface graphique Windows)
C: \ test> _
Espérons que ce soit OK jusqu'à présent, bien que le -mwindows
drapeau soit juste semi-documenté.
Construire sans cet indicateur semi-documenté, il faudrait indiquer plus spécifiquement à l'éditeur de liens la valeur de sous-système souhaitée, 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, fenêtres
C: \ test> objdump -x a.exe | findstr / i "^ sous-système"
Sous-système 00000002 (interface graphique Windows)
C: \ test> _
Cela a bien fonctionné, avec la chaîne d'outils GNU.
Mais qu'en est-il de la chaîne d'outils Microsoft, c'est-à-dire Visual C ++?
Eh bien, la construction en tant qu'exécutable de sous-système de console fonctionne bien:
C: \ test> msvc x.cpp user32.lib
x.cpp
C: \ test> dumpbin / headers x.exe | find / i "sous-système" | trouver / i "Windows"
3 sous-système (Windows CUI)
C: \ test> _
Cependant, avec la construction de la chaîne d'outils de Microsoft en tant que 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): erreur LNK2019: symbole externe non résolu _WinMain @ 16 référencé dans la fonction ___tmainCRTStartu
p
x.exe: erreur fatale LNK1120: 1 externes non résolus
C: \ test> _
Techniquement, c'est parce que l'éditeur de liens 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, l'éditeur de liens de Microsoft utilise un point d'entrée de bibliothèque d'exécution , la fonction où commence l'exécution du code machine, appelée winMainCRTStartup
, qui appelle Microsoft non standard WinMain
au lieu de standard main
.
Pas grand-chose à résoudre, cependant.
Tout ce que vous avez à faire est d'indiquer à l'éditeur de liens de Microsoft le point d'entrée à utiliser, à savoir mainCRTStartup
, qui appelle standard main
:
C: \ test> msvc x.cpp user32.lib / link / subsystem: windows / entrée: mainCRTStartup
x.cpp
C: \ test> dumpbin / headers x.exe | find / i "sous-système" | trouver / i "Windows"
2 sous-système (interface graphique Windows)
C: \ test> _
Pas de problème, mais très fastidieux. Et si obscur et caché que la plupart des programmeurs Windows, qui utilisent uniquement les outils non standard par défaut de Microsoft, ne le savent même pas et pensent à tort qu'un programme de sous-système Windows GUI «doit» avoir non standard WinMain
au lieu de standard main
. En passant, avec C ++ 0x, Microsoft aura un problème avec cela, car le compilateur doit alors annoncer s'il est autonome ou hébergé (lorsqu'il est hébergé, il doit prendre en charge le standard main
).
Quoi qu'il en soit, c'est la raison pour laquelle g ++ peut se plaindre de son WinMain
absence: c'est une fonction de démarrage non standard idiote dont les outils Microsoft ont besoin 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 le standard, main
même pour un programme de sous-système GUI.
Alors quel pourrait être le problème?
Eh bien, il vous manque probablement un fichiermain
. Et vous n'en avez probablement pas non WinMain
plus! Et puis g ++, après avoir recherché main
(pas de tel), et non standard de Microsoft WinMain
(pas de tel), rapporte 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 :(. texte + 0xd2 ): référence non définie
ce à `WinMain @ 16 '
collect2: ld a renvoyé 1 statut de sortie
C: \ test> _
All you have to do is to tell Microsoft's linker which entry point to use, namely mainCRTStartup, which calls standard main
. Existe-t-il un moyen de le faireEclipse CDT
car je n'utilise pas la ligne de commande. Mercimain
ou unWinMain
, ou, assurez-vous que le fichier pertinent est inclus dans le projet. Cheers,main
ouwinmain
? MerciPour résumer le post ci-dessus par Cheers et hth. - Alf, assurez-vous que vous avez défini
main()
ouWinMain()
défini et que g ++ devrait faire ce qu'il faut.Mon problème était que cela a
main()
été défini à l'intérieur d'un espace de noms par accident.la source
Je rencontrais cette erreur lors de la compilation de mon application avec SDL. Cela était dû au fait que SDL définissait 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 que l'en-tête SDL.h ne soit inclus.
la source
Essayez d'enregistrer votre fichier .c avant de créer. Je crois que votre ordinateur fait référence à un chemin vers un fichier sans aucune information à l'intérieur.
--A eu un problème similaire lors de la construction de projets C
la source
Vérifiez que tous les fichiers sont inclus dans votre projet:
J'ai eu cette même erreur après avoir mis à jour cLion. Après des heures de bricolage, j'ai remarqué qu'un de mes fichiers n'était pas inclus dans la cible du projet. Après l'avoir ajouté au projet actif, j'ai arrêté d'obtenir la référence non définie à winmain16 et le code compilé.
Modifier: il vaut également la peine de vérifier les paramètres de construction dans votre IDE.
(Je ne sais pas si cette erreur est liée à la mise à jour récente de l'EDI - pourrait être causale ou simplement corrélative. N'hésitez pas à commenter avec un aperçu de ce facteur!)
la source