2009-02-19 7 views
14

Les applications Windows GUI écrites en C/C++ ont 'WinMain' comme point d'entrée (plutôt que 'principal'). Ma compréhension de ceci est que le compilateur génère une fonction 'principale' appelée par le Runtime C. Cette fonction 'principale' configure l'environnement nécessaire pour l'interface graphique et appelle 'WinMain' (en spécifiant les poignées d'instance, etc.).Comment puis-je écrire une application Windows sans utiliser WinMain?

En bref, je crois que la console et le démarrage de l'application GUI diffèrent de la manière suivante:

application Console: C Runtime -> fonction 'principale' (codé à la main)

application GUI: C Runtime -> fonction « principale » (compilateur généré) -> fonction « WinMain » (codé à la main)

Je voudrais à la fois de valider cette compréhension et de savoir comment je peux coder manuellement Windows GUI avec juste une fonction 'principale' (c'est-à-dire sans avoir à écrire 'WinMain').

Répondre

15

Vous avez une compréhension incorrecte. La différence entre le principal et WinMain, à part un certain code d'initialisation de différence, est les paramètres passés à lui.

principaux ressemble à ceci:

int main(int argc, char* argv[]); 

Alors que WinMain ressemble à ceci:

int WINAPI WinMain(HINSTANCE hInstance, 
    HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, 
    int nCmdShow 
); 

Quelque chose doit configurer ces paramètres et de faire l'appel, et qui est le code de démarrage. Lorsque vous compilez et liez un programme, l'un des paramètres de l'éditeur de liens est le point d'entrée, et cela dépendra, selon la console ou l'application graphique, d'un code de démarrage différent.

Vous pouvez certainement écrire votre propre code de démarrage, il suffit d'aller dans votre répertoire source visuel C++ et vous pouvez trouver le code de démarrage, il s'appelle crt0.c et il se trouve dans le répertoire VC \ crt \ src.

6

Cela fonctionne dans l'autre sens. Il y a un fichier objet lié statiquement qui vient avec le compilateur qui contient le point d'entrée réel. Ce point d'entrée effectue l'initialisation et appelle ensuite votre point d'entrée (c'est-à-dire WinMain).

Ce que cette partie statique s'attend à appeler peut être modifié. Par exemple, dans Visual Studio, il existe un champ pour le nom du point d'entrée dans les paramètres de l'éditeur de liens.

+0

Alors, quel est l'ordre d'exécution dans les cas d'application console et GUI? La partie statique est-elle différente dans ces deux cas? Où se situe le runtime C? –

+0

D'abord, la partie statique est exécutée, puis elle appelle le point d'entrée implémenté par l'utilisateur. Il peut être différent ou identique, mais l'éditeur de liens peut lier l'appel à différents points d'entrée en fonction des paramètres. Vous pouvez penser à cette partie statique car elle fait partie du runtime C. – sharptooth

8

Avec Just principal, vous ne pouvez pas coder Winmain. Pour les justifications, à la suite des déclarations ont été tirées de http://blogs.msdn.com/oldnewthing/archive/2007/12/03/6644060.aspx

[Dans la programmation Windows,] Pourquoi pas le point d'entrée de l'application appelée principale? Eh bien, d'une part, le nom principal était déjà pris, et Windows n'avait pas le pouvoir de réserver une autre définition. Il n'y avait pas de comité de normalisation du langage C à l'époque; C était ce que Dennis a dit qu'il était, et il était à peine garanti que Dennis prendrait des mesures spéciales pour préserver la compatibilité du code source Windows dans toute future version du langage C. Puisque K & R ne spécifiait pas que les implémentations pouvaient étendre les formes acceptables de la fonction principale, il était tout à fait possible qu'il existait un compilateur C juridique qui rejetait les programmes déclarés incorrectement.La norme de langage C permet explicitement l'implémentation d'autres définitions spécifiques à l'implémentation, mais en exigeant que tous les compilateurs prennent en charge cette nouvelle version Windows spécifique afin de compiler les programmes Windows limiterait gratuitement l'ensemble des compilateurs que vous pouvez utiliser pour l'écriture Programmes Windows

Si vous avez réussi à surmonter cet obstacle, vous auriez le problème que la version Windows de principal devrait être quelque chose comme ceci:

int main(int argc, char *argv[], HINSTANCE hinst, 
     HINSTANCE hinstPrev, int nCmdShow); 

En raison de la liaison voie C a été réalisée, tout Les variations d'une fonction devaient s'accorder sur les paramètres qu'elles avaient en commun. Cela signifie que la version Windows devrait ajouter ses paramètres à la fin de la plus ancienne version principale, et alors vous devrez croiser les doigts et espérer que le langage C n'a jamais ajouté une autre version alternative de main. Si vous êtes allé cette route, vos doigts croisés vous ont échoué, car il devient qu'un troisième paramètre a été ajouté au principal quelque temps plus tard, et il en conflit avec votre version Windows-friendly. Supposons que vous ayez réussi à convaincre Dennis de ne pas autoriser cette version à trois paramètres de la fonction principale. Vous devez toujours définir ces deux premiers paramètres, ce qui signifie que le code de démarrage de chaque programme doit contenir un analyseur de ligne de commande. Retour dans les jours de 16 bits, personnes ont économisé pour sauver chaque octet. Leur disant, "Oh, et tous vos programmes vont être 2KB plus gros" ne vous feraient probablement pas beaucoup d'amis. Je veux dire, c'est quatre secteurs d'E/S sur une disquette!

Mais probablement la raison pour laquelle le point d'entrée Windows a reçu un nom différent est de souligner que c'est un environnement d'exécution différent . Si elle s'appelait main, les gens prendraient les programmes C conçus pour un environnement de console, les jetteraient dans leur compilateur Windows , puis les exécuteraient, avec des résultats désastreux.

Espérons que cela efface vos doutes.

Questions connexes