Dans un programme C/C++, comment le système (windows, linux, mac OS X) appelle-t-il la fonction main()

StackOverflow https://stackoverflow.com/questions/12332

  •  08-06-2019
  •  | 
  •  

Question

Je cherche une explication plus technique alors le système d'exploitation appelle la fonction.Quelqu'un peut-il m'aider ou me diriger vers un site Web ou un livre ?

Était-ce utile?

La solution

Le fichier .exe (ou équivalent sur d'autres plateformes) contient une adresse « point d'entrée ».En première approximation, le système d'exploitation charge les sections pertinentes du fichier .EXE dans la RAM, puis passe au point d'entrée.

Comme d'autres l'ont dit, ce point d'entrée ne sera pas "principal", mais fera plutôt partie de la bibliothèque d'exécution - il fera des choses comme initialiser des objets statiques, configurer les paramètres argc/argv, configurer stdin/stdout/stderr. , etc.Quand tout cela sera fait, il appellera votre fonction main().Lorsque main se termine, le runtime passe par un processus analogue consistant à renvoyer votre code de retour à l'environnement, à appeler des destructeurs statiques, à appeler des routines _atexit, etc.

Si vous disposez d'outils MS (peut-être pas ceux gratuits), alors vous disposez de toutes les sources d'exécution, et un moyen simple de les consulter est de mettre un point d'arrêt sur l'accolade fermante de votre méthode main() et de sauvegarder en une seule étape. dans le runtime.

Autres conseils

main() fait partie de la bibliothèque C et n'est pas une fonction système.Je ne sais pas pour OS X ou Linux, mais Windows démarre généralement un programme avec WinMainCRTStartup().Ce symbole lance votre processus, extrait les arguments de ligne de commande et l'environnement (argc, argv, end) et appelle main().Il est également responsable d'appeler tout code qui devrait s'exécuter après main(), comme atexit().

En regardant dans votre fichier Visual Studio, vous devriez pouvoir trouver l'implémentation par défaut de WinMainCRTStartup pour voir ce que ça fait.

Vous pouvez également définir votre propre fonction à appeler au démarrage, cela se fait en modifiant le "point d'entrée" dans les options de l'éditeur de liens.Il s'agit souvent d'une fonction qui ne prend aucun argument et renvoie un vide.

En ce qui concerne Windows, les fonctions du point d'entrée sont :

  • Console: void __cdecl mainCRTStartup( void ) {}
  • Interface graphique : void __stdcall WinMainCRTStartup( void ) {}
  • DLL : BOOL __stdcall _DllMainCRTStartup(HINSTANCE hinstDLL,DWORD fdwReason,void* lpReserved) {}

La seule raison de les utiliser sur le main/WinMain/DllMain normal est si vous souhaitez utiliser votre propre bibliothèque d'exécution (si vous souhaitez une taille de fichier plus petite ou des fonctionnalités personnalisées)

Pour les implémentations d'exécution personnalisées et d'autres astuces permettant d'obtenir des fichiers PE plus petits, consultez :

Expert C++/CLI (consultez la page 279) contient des détails très spécifiques sur les différents scénarios d'amorçage pour les assemblys CLR natifs, mixtes et purs.

Cela dépend du système d'exploitation.Sous OS X, il y a une trame dans l'en-tête mach qui contient l'adresse de début du registre EIP (pointeur d'instruction).

Une fois le binaire chargé, l'OS lance l'exécution à partir de cette adresse :

cristi:test diciu$ otool -l ./a.out | grep -A 10 LC_UNIXTHREAD
        cmd LC_UNIXTHREAD
    cmdsize 80
     flavor i386_THREAD_STATE
      count i386_THREAD_STATE_COUNT
[..]
        ss  0x00000000 eflags 0x00000000 eip 0x00001f8c cs  0x00000000
[..]

L'adresse est l'adresse de la fonction "start" du binaire :

cristi:test diciu$ nm ./a.out
0000200c D _NXArgc
00002008 D _NXArgv
00002000 D ___progname
00001fe0 t __dyld_func_lookup
00001000 A __mh_execute_header
[..]
00001f8c T start

Sous Mac OS X, c'est la fonction "start" qui est appelée en premier, avant même la fonction "main" :

(gdb) b start
Breakpoint 1 at 0x1f90
(gdb) b main
Breakpoint 2 at 0x1ff4
(gdb) r
Starting program: /Users/diciu/Programming/test/a.out 
Reading symbols for shared libraries ++. done

Breakpoint 1, 0x00001f90 in start ()

Si vous êtes intéressé par un livre sur Windows et l'API Win32, essayez

"Applications de programmation pour Microsoft Windows" par Jeffrey Richter.

Vous pouvez consulter les liens suivants :

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top