Wie ruft das System (Windows, Linux, Mac OS X) in einem C/C++-Programm die Funktion main() auf?

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

  •  08-06-2019
  •  | 
  •  

Frage

Ich suche nach einer technischeren Erklärung, als das Betriebssystem die Funktion aufruft.Kann mir jemand helfen oder mich auf eine Website oder ein Buch verweisen?

War es hilfreich?

Lösung

Die .exe-Datei (oder eine entsprechende Datei auf anderen Plattformen) enthält eine „Einstiegspunkt“-Adresse.In erster Näherung lädt das Betriebssystem die relevanten Abschnitte der .EXE-Datei in den RAM und springt dann zum Einstiegspunkt.

Wie bereits erwähnt, handelt es sich bei diesem Einstiegspunkt nicht um den „Haupteinstiegspunkt“, sondern um einen Teil der Laufzeitbibliothek. Er erledigt Dinge wie das Initialisieren statischer Objekte, das Einrichten der argc/argv-Parameter und das Einrichten von stdin/stdout/stderr , usw.Wenn das alles erledigt ist, ruft es Ihre main()-Funktion auf.Wenn main beendet wird, durchläuft die Laufzeit einen analogen Prozess, bei dem Ihr Rückkehrcode an die Umgebung zurückgegeben wird, statische Destruktoren aufgerufen werden, _atexit-Routinen aufgerufen werden usw.

Wenn Sie über MS-Tools verfügen (vielleicht nicht über die kostenlosen), dann verfügen Sie über die gesamte Laufzeitquelle, und eine einfache Möglichkeit, sie anzuzeigen, besteht darin, einen Haltepunkt in der schließenden Klammer Ihrer main()-Methode zu setzen und einen Schritt zurück zu machen in die Laufzeit.

Andere Tipps

main() ist Teil der C-Bibliothek und keine Systemfunktion.Ich weiß es nicht für OS X oder Linux, aber Windows startet normalerweise ein Programm mit WinMainCRTStartup().Dieses Symbol initiiert Ihren Prozess, extrahiert Befehlszeilenargumente und Umgebung (argc, argv, end) und Anrufe main().Es ist auch dafür verantwortlich, jeglichen Code aufzurufen, der danach ausgeführt werden soll main(), wie atexit().

Wenn Sie in Ihrer Visual Studio-Datei suchen, sollten Sie in der Lage sein, die Standardimplementierung von zu finden WinMainCRTStartup um zu sehen, was es bewirkt.

Sie können auch eine eigene Funktion definieren, die beim Start aufgerufen wird. Dies geschieht durch Ändern des „Einstiegspunkts“ in den Linker-Optionen.Dies ist häufig eine Funktion, die keine Argumente akzeptiert und eine Lücke zurückgibt.

Was Windows betrifft, sind die Einstiegspunktfunktionen:

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

Der einzige Grund, diese anstelle der normalen main/WinMain/DllMain zu verwenden, besteht darin, dass Sie Ihre eigene Laufzeitbibliothek verwenden möchten (wenn Sie eine kleinere Dateigröße oder benutzerdefinierte Funktionen wünschen).

Benutzerdefinierte Laufzeitimplementierungen und andere Tricks zum Erhalten kleinerer PE-Dateien finden Sie unter:

Experte für C++/CLI (siehe Seite 279) enthält sehr spezifische Details zu den verschiedenen Bootstrap-Szenarien für native, gemischte und reine CLR-Assemblys.

Es ist betriebssystemabhängig.In OS

Sobald die Binärdatei geladen ist, startet das Betriebssystem die Ausführung von dieser 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
[..]

Die Adresse ist die Adresse der „Start“-Funktion aus der Binärdatei:

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

In Mac OS X wird zuerst die „Start“-Funktion aufgerufen, noch vor der „Main“-Funktion:

(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 ()

Wenn Sie an einem Buch zum Thema Windows und Win32-API interessiert sind, probieren Sie es aus

„Anwendungen für Microsoft Windows programmieren“ von Jeffrey Richter.

Sie können einen Blick auf folgende Links werfen:

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top