Într-un program C/C ++, cum face sistemul (Windows, Linux, Mac OS X) să apeleze funcția principal ()

Caut o explicație mai tehnică, atunci OS cere funcția. Poate cineva să mă ajute sau să mă îndrume către un site sau o carte?

0
fr hi bn
Cine a votat să se închidă? Această întrebare pare perfect valabilă pentru mine. Aceasta este o întrebare bună!
adăugat autor Destructor, sursa

7 răspunsuri

main() is part of the C library and is not a system function. I don't know for OS X or Linux, but Windows usually starts a program with WinMainCRTStartup(). This symbol init your process, extract command line arguments and environment (argc, argv, end) and calls main(). It is also responsible of calling any code that should run after main(), like atexit().

Dacă căutați în fișierul Visual Studio, ar trebui să găsiți implementarea implicită a WinMainCRTStartup pentru a vedea ce face.

De asemenea, puteți defini o funcție proprie pentru a apela la pornire, aceasta se face prin schimbarea "punctului de intrare" în opțiunile linkerului. Aceasta este adesea o funcție care nu ia argumente și întoarce un gol.

0
adăugat

Expert C++/CLI (check around page 279) has very specific details of the different bootstrap scenarios for native, mixed, and pure CLR assemblies.

0
adăugat
0
adăugat

Fișierul .exe (sau echivalent pe alte platforme) conține o adresă "punct de intrare". La o primă aproximare, sistemul de operare încarcă secțiunile relevante ale fișierului .EXE în ram, apoi sări la punctul de intrare.

După cum au spus și ceilalți, acest punct de intrare nu va fi "principal", ci va fi o parte a bibliotecii runtime - va face lucruri ca inițializarea obiectelor statice, configurarea parametrilor argc/argv, setarea stdin/stdout/stderr , etc. Când se face totul, se va apela funcția principală (). Când ieșirile principale, runtime-ul trece printr-un proces analogic de trecere a codului de întoarcere înapoi în mediul înconjurător, apelând la destructori statici, apelând rutine _atexit etc.

Dacă aveți instrumentele MS (probabil nu cele libere), atunci aveți toată sursa de rulare și o modalitate ușoară de a vă uita la aceasta este să puneți un punct de întrerupere pe brațul de închidere al metodei principale() și să faceți un pas înapoi în timpul de execuție.

0
adăugat

În ceea ce privește ferestrele, funcțiile punctului de intrare sunt:

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

Singurul motiv pentru a le utiliza pe mainul principal/WinMain/DllMain este dacă doriți să utilizați propria dvs. bibliotecă de timp (dacă doriți dimensiune mai mică a fișierului sau caracteristici personalizate)

Pentru implementări personalizate de timp de execuție și alte trucuri pentru a obține fișiere mai mici PE, consultați:

0
adăugat

Este dependenta de sistemul de operare. În OS X, există un cadru în antetul mach care conține adresa de început pentru registrul EIP (indicatorul de instrucțiuni).

Odată ce binarul este încărcat, sistemul de operare lansează execuția din această adresă:

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
[..]

Adresa este adresa funcției "start" din binar:

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

În Mac OS X, funcția "start" este primită, chiar înainte de funcția "principală":

(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 ()
0
adăugat

Dacă sunteți interesat de o carte legată de Windows și Win32 API încercați

"Programarea aplicațiilor pentru Microsoft Windows" de Jeffrey Richter.

0
adăugat