Udostępnij za pośrednictwem


init_seg

Szczególne C++

Określa słowo kluczowe lub kod sekcji, która wpływa na kolejność, w którym uruchamiania wykonywany jest kod.

#pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )

Uwagi

Znaczenie terminów segment i sekcji są wymienne, w tym temacie.

Ponieważ inicjowanie globalnych obiektów statycznych może obejmować wykonywanie kodu, należy określić słowa kluczowego, które definiuje, kiedy obiekty mają być zbudowane.Jest to szczególnie ważne użyć init_seg pragmy w bibliotekach dołączanych dynamicznie (dll) lub w bibliotekach wymagających inicjalizacji.

Opcje, aby init_seg pragma są:

  • Kompilator
    Zarezerwowana dla inicjowania biblioteki uruchomieniowej c firmy Microsoft.Obiekty z tej grupy są zbudowane, najpierw.

  • lib
    Dostępne dla inicjowania dostawcy biblioteki klas strony trzeciej.Obiekty z tej grupy są zbudowane po oznaczone jako kompilatora , ale przed inne.

  • użytkownik
    Dostępny dla każdego użytkownika.Obiekty z tej grupy są konstruowane ostatnio.

  • Nazwa sekcji
    Umożliwia jawnej specyfikacji sekcji inicjalizacji.Obiekty Użytkownik określił Nazwa sekcji nie są niejawnie wykonane; Jednakże ich adresy są umieszczane w sekcji o nazwie przez Nazwa sekcji.

    Nazwa sekcji, które publikujesz będzie zawierać wskaźników do funkcji pomocnika, które będą konstruowania obiektów globalnych, zadeklarowany w tym module po pragma.

    Lista nazw nie należy używać podczas tworzenia sekcji, zobacz /Section.

  • FUNC nazwa
    Określa funkcję zwaną zamiast atexit gdy program kończy działanie.Ta funkcja pomocnicza wymaga również atexit ze wskaźnikiem do destruktora dla obiektu globalnego.Jeśli określony identyfikator funkcji w pragma formularza,

    int __cdecl myexit (void (__cdecl *pf)(void))
    

    następnie funkcja będzie wywoływana zamiast biblioteka uruchomieniowa c atexit.Umożliwia utworzenie listy destruktory, które będą musiały być wywoływane, gdy jesteś gotowy do zniszczenia obiektów.

Należy odroczyć inicjowania (na przykład w bibliotece DLL) można jawnie określić nazwę sekcji.Następnie należy wywołać konstruktory dla każdego obiektu statycznego.

Istnieją nie stawiać cudzysłów wokół identyfikator atexit zastąpienia.

Obiekty nadal zostaną umieszczone w sekcjach, zdefiniowane przez innych pragmas XXX_seg.

Obiekty, które są zadeklarowane w module nie zostaną automatycznie zainicjowane przez c run-time.Trzeba będzie zrobić tego samodzielnie.

Domyślnie init_seg sekcje są tylko do odczytu.Jeśli nazwa sekcji.CRT, kompilator po cichu zmieni ten atrybut tylko do odczytu, nawet jeśli jest ona oznaczona jako przeczytana, zapisu.

Nie można określić init_seg więcej niż jeden raz w jednostce tłumaczenia.

Nawet jeśli obiekt nie ma konstruktora zdefiniowane przez użytkownika, konstruktora, nie są jawnie zdefiniowane w kodzie, kompilator może wygenerować (na przykład powiązać wskaźniki tabeli v-table).Kod będzie więc wywołanie konstruktora generowanych przez kompilator.

Przykład

// 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();
}
  

Zobacz też

Informacje

Dyrektywy pragma i __Pragma słowa kluczowego