__clrcall

Určuje, že funkci lze volat pouze ze spravovaného kódu. Použijte __clrcall pro všechny virtuální funkce, které budou volána pouze ze spravovaného kódu. Tuto konvenci volání však nelze použít pro funkce, které budou volána z nativního kódu. Modifikátor __clrcall je specifický pro Společnost Microsoft.

Použití __clrcall ke zlepšení výkonu při volání ze spravované funkce do virtuální spravované funkce nebo ze spravované funkce do spravované funkce prostřednictvím ukazatele.

Vstupní body jsou samostatné, funkce generované kompilátorem. Pokud má funkce nativní i spravované vstupní body, jednou z nich bude skutečná funkce s implementací funkce. Druhá funkce bude samostatnou funkcí (thunk), která volá do skutečné funkce a umožňuje modulu CLR (Common Language Runtime) provádět PInvoke. Když funkci označíte jako __clrcall, označíte, že implementace funkce musí být MSIL a že nativní funkce vstupního bodu nebude generována.

Při přebírání adresy nativní funkce, pokud není zadán __clrcall , kompilátor používá nativní vstupní bod. __clrcall značí, že je funkce spravovaná a není nutné procházet přechodem ze spravovaného na nativní. V takovém případě kompilátor používá spravovaný vstupní bod.

Pokud /clr se použije (ne /clr:pure nebo /clr:safe) a __clrcall se nepoužije, přebírání adresy funkce vždy vrátí adresu nativní funkce vstupního bodu. Při použití __clrcall se nevytvořila funkce nativního vstupního bodu, takže získáte adresu spravované funkce, nikoli funkci thunk vstupního bodu. Další informace naleznete v tématu Double Thunking. Možnosti kompilátoru /clr:pure a /clr:safe jsou v sadě Visual Studio 2015 zastaralé a v sadě Visual Studio 2017 nejsou podporované.

/clr (Common Language Runtime Compilation) znamená, že všechny funkce a ukazatele funkcí jsou __clrcall a kompilátor nepovolí funkci uvnitř compilandu, aby byla označena cokoli jiného než __clrcall. Při použití /clr:pure lze __clrcall zadat pouze u ukazatelů funkce a externích deklarací.

Funkce __clrcall můžete přímo volat z existujícího kódu C++, který byl zkompilován pomocí /clr, pokud má tato funkce implementaci jazyka MSIL. __clrcall funkce nelze volat přímo z funkcí, které mají vložený asm, a volat například vnitřní funkce specifické pro procesor, a to i v případě, že jsou tyto funkce zkompilovány s /clr.

__clrcall ukazatele funkce jsou určeny pouze k použití v doméně aplikace, ve které byly vytvořeny. Místo předávání ukazatelů funkce __clrcall napříč doménami aplikace použijte CrossAppDomainDelegate. Další informace naleznete v tématu Domény aplikace a Visual C++.

Příklady

Všimněte si, že když je funkce deklarována pomocí __clrcall, kód se vygeneruje v případě potřeby, například při zavolání funkce.

// 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

Následující ukázka ukazuje, že můžete definovat ukazatel funkce, tak, že deklarujete, že ukazatel funkce bude vyvolán pouze ze spravovaného kódu. Kompilátor tak může přímo volat spravovanou funkci a vyhnout se nativnímu vstupnímu bodu (problém s dvojitým zápisem).

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

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

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

Viz také

Konvence předávání a pojmenování argumentů
Klíčová slova