init_seg
pragma
C++ Özel
Başlangıç kodunun yürütülma sırasını etkileyen bir anahtar sözcük veya kod bölümü belirtir.
Sözdizimi
#pragma init_seg(
{compiler
| |lib
user
| "section-name" [,
func-name ] })
Açıklamalar
Segment ve bölüm terimleri bu makalede aynı anlama sahiptir.
Genel statik nesneleri başlatmak için bazen kod gerektiğinden, nesnelerin ne zaman yapılacağını belirtmeniz gerekir. Özellikle, dinamik bağlantı kitaplıklarında (DLL'ler) veya başlatma gerektiren kitaplıklarda kullanılması init_seg
pragma önemlidir.
seçenekleri init_seg
pragma şunlardır:
compiler
Microsoft C çalışma zamanı kitaplığı başlatma için ayrılmıştır. Bu gruptaki nesneler önce oluşturulur.
lib
Üçüncü taraf sınıf kitaplığı satıcılarının başlatmaları için kullanılabilir. Bu gruptaki nesneler, olarak compiler
işaretlenenlerden sonra ancak diğerlerinden önce oluşturulur.
user
Herhangi bir kullanıcı tarafından kullanılabilir. Bu gruptaki nesneler en son oluşturulur.
bölüm adı
Başlatma bölümünün açık belirtimine izin verir. Kullanıcı tarafından belirtilen bölüm adı içindeki nesneler örtük olarak oluşturulur. Ancak adresleri, bölüm adıyla adlandırılan bölüme yerleştirilir.
Verdiğiniz bölüm adı, bu modülde sonrasında bildirilen genel nesneleri oluşturan yardımcı işlevlere pragma yönelik işaretçiler içerir.
Bölüm oluştururken kullanmamanız gereken adların listesi için bkz /SECTION
. .
func-name
Programdan çıktığı zaman yerine atexit
çağrılacak bir işlev belirtir. Bu yardımcı işlevi, genel nesnenin yıkıcısına yönelik bir işaretçiyle de çağırır atexit
. Formda pragma bir işlev tanımlayıcısı belirtirseniz,
int __cdecl myexit (void (__cdecl *pf)(void))
ardından işleviniz C çalışma zamanı kitaplığının atexit
yerine çağrılır. Nesneleri yok etmeye hazır olduğunuzda çağıracak yıkıcıların listesini oluşturmanıza olanak tanır.
Başlatmayı ertelemeniz gerekiyorsa (örneğin, bir DLL'de), bölüm adını açıkça belirtmeyi seçebilirsiniz. Kodunuzun daha sonra her statik nesne için oluşturucuları çağırması gerekir.
Değiştirme için atexit
tanımlayıcının çevresinde tırnak işareti yoktur.
Nesneleriniz yine de diğer XXX_seg
pragma yönergeler tarafından tanımlanan bölümlere yerleştirilir.
Modülde bildirilen nesneler C çalışma zamanı tarafından otomatik olarak başlatılmaz. Kodunuzun başlatmayı yapması gerekir.
Varsayılan olarak, init_seg
bölümler salt okunur durumdadır. Bölüm adı ise .CRT
, derleyici okuma, yazma olarak işaretlenmiş olsa bile özniteliğini sessizce salt okunur olarak değiştirir.
Çeviri biriminde birden çok kez belirtemezsiniz init_seg
.
Nesnenizin kodda açıkça tanımlanmış kullanıcı tanımlı bir oluşturucusı olmasa bile, derleyici sizin için bir oluşturucu oluşturabilir. Örneğin, v-tablo işaretçilerini bağlamak için bir tane oluşturabilir. Gerektiğinde kodunuz derleyici tarafından oluşturulan oluşturucuyu çağırır.
Örnek
// 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();
}
A()
A()
A()
~A()
~A()
~A()
Ayrıca bkz.
Pragma yönergeleri ve __pragma
ve _Pragma
anahtar sözcükleri