Inizializzazione CRTCRT Initialization

In questo argomento viene descritto come CRT inizializza gli stati globali nel codice nativo.This topic describes how the CRT initializes global states in native code.

Per impostazione predefinita, il linker include la libreria CRT che fornisce il proprio codice di avvio.By default, the linker includes the CRT library, which provides its own startup code. Questo codice di avvio inizializza la libreria CRT, chiama gli inizializzatori globali e quindi chiama la funzione main fornita dall'utente per le applicazioni console.This startup code initializes the CRT library, calls global initializers, and then calls the user-provided main function for console applications.

Inizializzazione di un oggetto globaleInitializing a Global Object

Esaminare il codice seguente:Consider the following code:

int func(void)  
{  
    return 3;  
}  

int gi = func();  

int main()  
{  
    return gi;  
}  

Secondo lo standard C/C++, func() deve essere chiamato prima che main() venga eseguito.According to the C/C++ standard, func() must be called before main() is executed. Ma chi lo chiama?But who calls it?

Un modo per determinarlo è quello di impostare un punto di interruzione in func(), eseguire il debug dell'applicazione ed esaminare lo stack.One way to determine this is to set a breakpoint in func(), debug the application, and examine the stack. Ciò è possibile poiché il codice sorgente CRT è incluso in Visual Studio.This is possible because the CRT source code is included with Visual Studio.

Quando si esplorano le funzioni sullo stack, si noterà che CRT scorre in ciclo un elenco di puntatori a funzione e chiama ognuno nel momento in cui li incontra.When you browse the functions on the stack, you will find that the CRT is looping through a list of function pointers and calling each one as it encounters them. Queste funzioni sono simili a func() o ai costruttori per le istanze di classe.These functions are either similar to func() or constructors for class instances.

CRT ottiene l'elenco dei puntatori a funzione dal compilatore di Visual C++.The CRT obtains the list of function pointers from the Visual C++ compiler. Quando il compilatore rileva un inizializzatore globale, viene generato un inizializzatore dinamico nella sezione .CRT$XCU (dove CRT è il nome della sezione e XCU è il nome del gruppo).When the compiler sees a global initializer, it generates a dynamic initializer in the .CRT$XCU section (where CRT is the section name and XCU is the group name). Per ottenere un elenco di tali inizializzatori dinamici eseguire il comando dumpbin /all main.obj, quindi individuare la sezione .CRT$XCU (se main.cpp viene compilato come file C++, non come file C).To obtain a list of those dynamic initializers run the command dumpbin /all main.obj, and then search the .CRT$XCU section (when main.cpp is compiled as a C++ file, not a C file). Sarà simile a quanto segue:It will be similar to the following:

SECTION HEADER #6  
.CRT$XCU name  
       0 physical address  
       0 virtual address  
       4 size of raw data  
     1F2 file pointer to raw data (000001F2 to 000001F5)  
     1F6 file pointer to relocation table  
       0 file pointer to line numbers  
       1 number of relocations  
       0 number of line numbers  
40300040 flags  
         Initialized Data  
         4 byte align  
         Read Only  

RAW DATA #6  
  00000000: 00 00 00 00                                      ....  

RELOCATIONS #6  
                                                Symbol    Symbol  
 Offset    Type              Applied To         Index     Name  
 --------  ----------------  -----------------  --------  ------  
 00000000  DIR32                      00000000         C  ??__Egi@@YAXXZ (void __cdecl `dynamic initializer for 'gi''(void))  

CRT definisce due puntatori:The CRT defines two pointers:

  • __xc_a in .CRT$XCA__xc_a in .CRT$XCA

  • __xc_z in .CRT$XCZ__xc_z in .CRT$XCZ

    Entrambi i gruppi non hanno alcun altro simbolo definito tranne __xc_a e __xc_z.Both groups do not have any other symbols defined except __xc_a and __xc_z.

    Ora, quando il linker legge i vari gruppi .CRT, li combina in una sezione e li ordina alfabeticamente.Now, when the linker reads various .CRT groups, it combines them in one section and orders them alphabetically. Ciò significa che gli inizializzatori globali definiti dall'utente (che il compilatore di Visual C++ inserisce in .CRT$XCU) verranno sempre dopo .CRT$XCA e prima di .CRT$XCZ.This means that the user-defined global initializers (which the Visual C++ compiler puts in .CRT$XCU) will always come after .CRT$XCA and before .CRT$XCZ.

    La sezione sarà simile alla seguente:The section will resemble the following:

.CRT$XCA  
            __xc_a  
.CRT$XCU  
            Pointer to Global Initializer 1  
            Pointer to Global Initializer 2  
.CRT$XCZ  
            __xc_z  

Pertanto, la libreria CRT utilizza sia __xc_a che __xc_z per determinare l'inizio e la fine dell'elenco di inizializzatori globali a causa del modo in cui vengono disposti nella memoria dopo che l'immagine viene caricata.So, the CRT library uses both __xc_a and __xc_z to determine the start and end of the global initializers list because of the way in which they are laid out in memory after the image is loaded.

Vedere ancheSee Also

CRT Library Features (Funzionalità della libreria CRT)CRT Library Features