Share via


__clrcall

bir işlevin yalnızca yönetilen koddan çağrılabileceğini belirtir. yalnızca yönetilen koddan çağrılacak tüm sanal işlevler için __clrcall kullanın. Ancak bu çağırma kuralı, yerel koddan çağrılacak işlevler için kullanılamaz. __clrcall değiştirici Microsoft'a özgüdür.

yönetilen bir işlevden sanal yönetilen işleve veya yönetilen işlevden işaretçi aracılığıyla yönetilen işleve çağrı yaparken performansı geliştirmek için __clrcall kullanın.

Giriş noktaları ayrı, derleyici tarafından oluşturulan işlevlerdir. bir işlevin hem yerel hem de yönetilen giriş noktaları varsa, bunlardan biri işlev uygulamasıyla gerçek işlev olacaktır. Diğer işlev, gerçek işleve çağrı yapan ve ortak dil çalışma zamanının PInvoke gerçekleştirmesine izin veren ayrı bir işlev (thunk) olacaktır. bir işlevi __clrcall olarak işaretlerken, işlev uygulamasının MSIL olması gerektiğini ve yerel giriş noktası işlevinin oluşturulmayacağını belirtirsiniz.

__clrcall belirtilmezse yerel işlevin adresini alırken, derleyici yerel giriş noktasını kullanır. __clrcall işlevin yönetildiğini ve yönetilenden yerele geçişten geçmenin gerek olmadığını gösterir. Bu durumda derleyici yönetilen giriş noktasını kullanır.

(veya /clr:safedeğil/clr:pure) kullanıldığında ve __clrcall kullanılmadığında /clr , bir işlevin adresini almak her zaman yerel giriş noktası işlevinin adresini döndürür. __clrcall kullanıldığında, yerel giriş noktası işlevi oluşturulmaz, bu nedenle bir giriş noktası işlev değil yönetilen işlevin adresini alırsınız. Daha fazla bilgi için bkz . Çift Thunking. /clr:pure ve /clr:safe derleyici seçenekleri Visual Studio 2015'te kullanım dışıdır ve Visual Studio 2017'de desteklenmez.

/clr (Ortak Dil Çalışma Zamanı Derlemesi), tüm işlevlerin ve işlev işaretçilerinin __clrcall olduğunu ve derleyicinin compiland içindeki bir işlevin __clrcall dışında bir şeyin işaretlenmesine izin vermediğini belirtir. /clr:pure kullanıldığında, __clrcall yalnızca işlev işaretçilerinde ve dış bildirimlerde belirtilebilir.

bir MSIL uygulamasına sahip olduğu sürece ,clr kullanılarak derlenen mevcut C++ kodundan __clrcall işlevlerini doğrudan çağırabilirsiniz. __clrcall işlevleri doğrudan satır içi asm içeren işlevlerden çağrılamaz ve örneğin, bu işlevler ile /clrderlenmiş olsa bile CPU'ya özgü iç bilgileri çağıramaz.

__clrcall işlev işaretçileri yalnızca oluşturuldukları uygulama etki alanında kullanılmaya yöneliktir. __clrcall işlev işaretçilerini uygulama etki alanları arasında geçirmek yerine kullanınCrossAppDomainDelegate. Daha fazla bilgi için bkz . Uygulama Etki Alanları ve Visual C++.

Örnekler

bir işlev __clrcall ile bildirildiğinde, gerektiğinde kod oluşturulacağını unutmayın; örneğin işlev çağrıldığında.

// clrcall2.cpp
// compile with: /clr
using namespace System;
int __clrcall Func1() {
   Console::WriteLine("in Func1");
   return 0;
}

// Func1 hasn't been used at this point (code has not been generated),
// so runtime returns the adddress of a stub to the function
int (__clrcall *pf)() = &Func1;

// code calls the function, code generated at difference address
int i = pf();   // comment this line and comparison will pass

int main() {
   if (&Func1 == pf)
      Console::WriteLine("&Func1 == pf, comparison succeeds");
   else
      Console::WriteLine("&Func1 != pf, comparison fails");

   // even though comparison fails, stub and function call are correct
   pf();
   Func1();
}
in Func1
&Func1 != pf, comparison fails
in Func1
in Func1

Aşağıdaki örnek, işlev işaretçisinin yalnızca yönetilen koddan çağrılacağını bildirmeniz gibi bir işlev işaretçisi tanımlayabildiğinizi gösterir. Bu, derleyicinin yönetilen işlevi doğrudan çağırmasına ve yerel giriş noktasından (çift thunk sorunu) kaçınmasına olanak tanır.

// clrcall3.cpp
// compile with: /clr
void Test() {
   System::Console::WriteLine("in Test");
}

int main() {
   void (*pTest)() = &Test;
   (*pTest)();

   void (__clrcall *pTest2)() = &Test;
   (*pTest2)();
}

Ayrıca bkz.

Bağımsız Değişkeni Geçirme ve Adlandırma Kuralları
Anahtar Sözcükler