Share via


__clrcall

Gibt an, dass eine Funktion nur aus verwaltetem Code aufgerufen werden kann. Verwenden Sie __clrcall für alle virtuellen Funktionen, die nur aus verwaltetem Code aufgerufen werden. Allerdings kann diese Aufrufkonvention nicht für Funktionen verwendet werden, die vom nativen Code aufgerufen werden. Der __clrcall Modifizierer ist microsoftspezifisch.

Verwenden Sie __clrcall , um die Leistung beim Aufrufen von einer verwalteten Funktion zu einer virtuellen verwalteten Funktion oder von verwalteter Funktion bis hin zu verwalteter Funktion über Zeiger zu verbessern.

Einstiegspunkte sind separate, vom Compiler generierte Funktionen. Wenn eine Funktion sowohl über die systemeigenen als auch über verwaltete Einstiegspunkte verfügt, ist eine von ihnen die tatsächliche Funktion mit der Funktionsimplementierung. Die andere Funktion ist eine separate Funktion (ein Thunk), welche die tatsächliche Funktion aufruft und die Common Language Runtime PInvoke ausführen lässt. Wenn Sie eine Funktion als __clrcall markieren, müssen Sie angeben, dass die Funktionsimplementierung MSIL sein muss und dass die systemeigene Einstiegspunktfunktion nicht generiert wird.

Wenn die Adresse einer systemeigenen Funktion verwendet wird, wenn __clrcall nicht angegeben ist, verwendet der Compiler den systemeigenen Einstiegspunkt. __clrcall gibt an, dass die Funktion verwaltet wird und es nicht erforderlich ist, den Übergang von verwaltet zu systemeigenen zu durchlaufen. In diesem Fall verwendet der Compiler den verwalteten Einstiegspunkt.

Wenn /clr (nicht /clr:pure oder /clr:safe) verwendet wird und __clrcall nicht verwendet wird, gibt die Adresse einer Funktion immer die Adresse der systemeigenen Einstiegspunktfunktion zurück. Wenn __clrcall verwendet wird, wird die systemeigene Einstiegspunktfunktion nicht erstellt, sodass Sie die Adresse der verwalteten Funktion und keine Einstiegspunkt-Thunk-Funktion abrufen. Weitere Informationen finden Sie unter Double Thunking. Die Optionen "/clr:pure " und "/clr:safe compiler" sind in Visual Studio 2015 veraltet und werden in Visual Studio 2017 nicht unterstützt.

/clr (Common Language Runtime Compilation) bedeutet, dass alle Funktionen und Funktionszeiger __clrcall sind, und der Compiler erlaubt nicht, dass eine Funktion innerhalb des Kommislandes als __clrcall gekennzeichnet werden kann. Wenn /clr:pure verwendet wird, kann __clrcall nur für Funktionszeiger und externe Deklarationen angegeben werden.

Sie können direkt __clrcall Funktionen aus vorhandenem C++-Code aufrufen, der mithilfe von /clr kompiliert wurde, solange diese Funktion über eine MSIL-Implementierung verfügt. __clrcall Funktionen können nicht direkt von Funktionen aufgerufen werden, die inline asm enthalten und CPU-spezifische systeminterne Funktionen aufrufen, z. B. auch dann, wenn diese Funktionen kompiliert /clrwerden.

__clrcall Funktionszeiger sollen nur in der Anwendung verwendet werden Standard in der sie erstellt wurden. Verwenden Sie anstelle __clrcall Funktionszeiger über anwendungsübergreifende Aufgaben Standard.CrossAppDomainDelegate Weitere Informationen finden Sie unter Application Do Standard s und Visual C++.

Beispiele

Beachten Sie, dass bei der Deklaration einer Funktion mit __clrcall Code bei Bedarf generiert wird, z. B. beim Aufrufen der Funktion.

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

Das folgende Beispiel zeigt, wie ein Funktionszeiger so definiert werden kann, dass deklariert wird, dass der Funktionszeiger nur von verwaltetem Code aufgerufen wird. Dies ermöglicht es dem Compiler, die verwaltete Funktion direkt aufzurufen und den systemeigenen Einstiegspunkt (doppeltes Thunk-Problem) zu vermeiden.

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

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

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

Siehe auch

Argumentübergabe und Benennungskonventionen
Schlüsselwörter