__clrcall

Specifici di Microsoft

Specifica che una funzione può essere chiamata solo da codice gestito.Usa __clrcall per tutte le funzioni virtuali che verranno chiamate solo da codice gestito.Tuttavia questa convenzione di chiamata non può essere utilizzata per funzioni che verranno chiamate dal codice nativo.

Usa __clrcall per migliorare le prestazioni durante la chiamata da una funzione gestita a una funzione gestita virtuale o da una funzione gestita a funzione gestita tramite puntatore.

Punti di ingresso sono funzioni separate, generato dal compilatore.Se entrambi i punti di ingresso nativo e gestito dispone di una funzione, una di esse sarà la funzione effettiva con l'implementazione della funzione.L'altra funzione sarà una funzione distinta (un thunk) che chiama la funzione effettivo e consente a common language runtime di eseguire PInvoke.Quando si contrassegna una funzione come __clrcall, è possibile indicare l'implementazione della funzione deve essere MSIL e la funzione di punto di ingresso nativo non verrà generata.

Quando l'indirizzo di una funzione nativa Se __clrcall non è specificato, il compilatore utilizza il punto di ingresso nativo.__clrcallindica che la funzione è gestita e vi è dover passare attraverso la transizione da non gestito a nativo.In tal caso, il compilatore utilizza il punto di ingresso gestito.

Quando /clr (non /clr:pure o /clr:safe) viene utilizzato e __clrcall non è viene utilizzata, tenendo sempre l'indirizzo di una funzione restituisce l'indirizzo della funzione di punto di ingresso nativo.Quando __clrcall è utilizzato, la funzione di punto di ingresso nativo non viene creata, in modo che si ottiene l'indirizzo della funzione gestita, non una funzione thunk del punto di ingresso.Per ulteriori informazioni, vedere Doppio thunk (C++).

/clr (Compilazione Common Language Runtime)implica che tutte le funzioni e i puntatori a funzione sono __clrcall e il compilatore non consente una funzione all'interno del modulo per contrassegnare un valore diverso da __clrcall.Quando /clr:pure viene utilizzata, __clrcall può essere specificata solo su puntatori a funzione e le dichiarazioni esterne.

È possibile chiamare direttamente __clrcall le funzioni da codice C++ esistente che è stata compilata con /clr , purché tale funzione è un'implementazione di MSIL.__clrcallfunzioni non possono essere chiamate direttamente da funzioni con assembly inline che chiamare intrinisics specifico della CPU, ad esempio, anche se tali funzioni vengono compilate con /clr.

__clrcallpuntatori a funzione sono solo semplici da utilizzare nel dominio applicazione in cui sono stati creati.Invece di passaggio __clrcall puntatori a funzione tra più domini applicazione, utilizzare CrossAppDomainDelegate.Per ulteriori informazioni, vedere Domini applicazione e Visual C++.

Esempio

// clrcall.cpp
// compile with: /clr:oldSyntax /LD
void __clrcall Test1( ) {}
void (__clrcall *fpTest1)( ) = &Test1;

Si noti che quando una funzione viene dichiarata con __clrcall, verrà generato il codice quando necessario; ad esempio, quando viene chiamata funzione.

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

Nell'esempio riportato di seguito viene illustrato che è possibile definire un puntatore a funzione, che si dichiara che il puntatore a funzione verrà richiamato solo da codice gestito.Ciò consente al compilatore di chiamare direttamente la funzione gestita ed evitare il punto di ingresso nativo (problema del doppio thunk).

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

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

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

Vedere anche

Riferimenti

Passaggio e convenzioni di denominazione dell'argomento

Parole chiave C++