init_seg
C++-Besondere
Gibt ein Schlüsselwort oder einen Codeabschnitt an, die die Reihenfolge auswirkt, in der Startcode ausgeführt wird.
#pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
Hinweise
Die Bedeutung der Ausdrücke Segment und - Abschnitt in diesem Thema sind austauschbar.
Da Initialisierung einer globalen statischen Objekten Code auszuführen, umfassen kann, müssen Sie ein Schlüsselwort angeben, die definiert, wann die Objekte erstellt werden sollen.Dies ist besonders wichtig, das init_seg Pragma in den DLLs (Dynamic Link Libraries) oder Bibliotheken zu verwenden, für die eine Initialisierung erforderlich ist.
Die Optionen zum init_seg Pragma sind:
Compiler
Reserviert für Microsoft C-Laufzeitbibliotheks Initialisierung.Objekte in dieser Gruppe werden zuerst erstellt.lib
Verfügbar für die von Drittanbietern Initialisierungen der Klassenbibliothekanbieter.Objekte in dieser Gruppe werden nach den Filtern erstellt, die als Compiler aber vor allen anderen gekennzeichnet sind.Benutzer
Verfügbar für einen beliebigen Benutzer.Objekte in dieser Gruppe werden zuletzt erstellt.Abschnittsname
Ermöglicht die explizite Angabe des Abschnitts Initialisierung.Objekte in einem vom Benutzer angegebenen Abschnittsnamen werden nicht implizit erstellt. Allerdings werden die Adressen im Abschnitt gespeichert, der von Abschnittsnamenbenannt ist.Der Abschnittsname enthält, geben Sie den Zeiger auf den Hilfsfunktionen, die die globalen Objekte erstellen, die in diesem Modul nach dem Pragma deklariert werden.
Bei einer Liste von Namen, die Sie verwenden sollten, wenn ein Abschnitt erstellt wird, finden Sie unter /SECTION.
Funktions-NAME
Gibt eine statt an atexit-Funktion, die aufgerufen werden soll, wenn das Programm beendet.Diese Hilfsfunktion ruft außerdem atexit mit einem Zeiger auf den Destruktor für das globale Objekt an.Wenn Sie einen Funktionsbezeichner im Pragma des Formulars angeben.int __cdecl myexit (void (__cdecl *pf)(void))
Anschließend werden die Funktion anstelle atexitder C-Laufzeit-Bibliothek aufgerufen.Dadurch können Sie eine Liste mit Destruktoren erstellen, die aufgerufen werden muss, wenn Sie bereit sind, die Objekte zu löschen.
Wenn Sie die Initialisierung verzögern müssen (z. B. in einer DLL) Sie können auch den Abschnittsnamen explizit anzugeben.Sie müssen die Konstruktoren für jedes statische Objekt aufrufen.
Es gibt keine Anführungszeichen um den Bezeichner für den atexit ein Ersatz.
Die Objekte werden in die Abschnitte platziert, die von der anderen XXX_seg-Pragmen definiert sind.
Die Objekte, die im Modul deklariert wurden, werden nicht automatisch von der C-Laufzeit initialisiert.Sie müssen die ausführen soll.
Standardmäßig sind init_seg-Abschnitte schreibgeschützt.Wenn der Abschnittsname .CRT ist, nimmt der Compiler automatisch das Attribut schreibgeschützt markiert ist, auch wenn er als gelesen, geschrieben.
Sie können init_seg in einer Übersetzungseinheit nicht mehrmals angeben.
Auch wenn das Objekt keinen benutzerdefinierten Konstruktor verfügt, wird möglicherweise ein Konstruktor im Code nicht explizit definiert wurde, ein (z. B. Vtable-Zeiger binden).Daher muss der Code den vom Compiler generierten Konstruktor aufrufen.
Beispiel
// pragma_directive_init_seg.cpp
#include <stdio.h>
#pragma warning(disable : 4075)
typedef void (__cdecl *PF)(void);
int cxpf = 0; // number of destructors we need to call
PF pfx[200]; // pointers to destructors.
int myexit (PF pf) {
pfx[cxpf++] = pf;
return 0;
}
struct A {
A() { puts("A()"); }
~A() { puts("~A()"); }
};
// ctor & dtor called by CRT startup code
// because this is before the pragma init_seg
A aaaa;
// The order here is important.
// Section names must be 8 characters or less.
// The sections with the same name before the $
// are merged into one section. The order that
// they are merged is determined by sorting
// the characters after the $.
// InitSegStart and InitSegEnd are used to set
// boundaries so we can find the real functions
// that we need to call for initialization.
#pragma section(".mine$a", read)
__declspec(allocate(".mine$a")) const PF InitSegStart = (PF)1;
#pragma section(".mine$z",read)
__declspec(allocate(".mine$z")) const PF InitSegEnd = (PF)1;
// The comparison for 0 is important.
// For now, each section is 256 bytes. When they
// are merged, they are padded with zeros. You
// can't depend on the section being 256 bytes, but
// you can depend on it being padded with zeros.
void InitializeObjects () {
const PF *x = &InitSegStart;
for (++x ; x < &InitSegEnd ; ++x)
if (*x) (*x)();
}
void DestroyObjects () {
while (cxpf>0) {
--cxpf;
(pfx[cxpf])();
}
}
// by default, goes into a read only section
#pragma init_seg(".mine$m", myexit)
A bbbb;
A cccc;
int main () {
InitializeObjects();
DestroyObjects();
}