__clrcall
Spécifique à Microsoft
Spécifie qu'une fonction ne peut être appelée à partir du code managé.Utilisation __clrcall pour toutes les fonctions virtuelles qui sera appelées à partir du code managé.Toutefois cette convention d'appel ne peut pas être utilisée pour les fonctions qui seront appelées à partir du code natif.
Utilisation __clrcall pour améliorer les performances lors de l'appel à partir d'une fonction managée à une fonction managée virtuelle ou d'une fonction managée à une fonction managée par le biais de pointeur.
Points d'entrée sont des fonctions distinctes, généré par le compilateur.Si une fonction a deux points d'entrée natif et managé, l'un d'eux sera la fonction réelle avec l'implémentation de fonction.L'autre fonction sera une fonction distincte (un thunk) qui appelle la fonction réelle et le common language runtime vous permet d'effectuer de PInvoke.Lors du marquage d'une fonction en tant que __clrcall, vous indiquez la mise en oeuvre de la fonction doit être MSIL et que la fonction de point d'entrée natif ne sera pas générée.
Lorsque vous prenez l'adresse d'une fonction native si __clrcall n'est pas spécifié, le compilateur utilise le point d'entrée natif.__clrcallIndique que la fonction est gérée et il est inutile de passer par la transition de managé native.Dans ce cas, le compilateur utilise le point d'entrée managé.
Lorsque /clr (pas /clr:pure ou /clr:safe) est utilisé et __clrcall est ne pas utilisée, tirant toujours l'adresse d'une fonction renvoie l'adresse de la fonction de point d'entrée natif.Lorsque __clrcall est utilisé, la fonction de point d'entrée natif n'est pas créée, donc vous obtenez l'adresse de la fonction managée, pas une fonction thunk de point d'entrée.Pour plus d'informations, consultez Double conversion de code (thunking) (C++).
/clr (Compilation pour le Common Language Runtime)implique que toutes les fonctions et les pointeurs fonction sont __clrcall et le compilateur ne permettra pas une fonction à l'intérieur du module (compiland) être marquée quoi que ce soit autre que __clrcall.Lorsque /clr:pure est utilisé, __clrcall peut être spécifié uniquement sur des pointeurs de fonction et des déclarations externes.
Vous pouvez appeler directement __clrcall fonctions à partir de code C++ existant qui a été compilé à l'aide de /clr tant que cette fonction a une implémentation MSIL.__clrcallles fonctions ne peuvent pas être appelées directement à partir de fonctions inline asm et appellent intrinisics spécifique au processeur, par exemple, même si ces fonctions sont compilées avec /clr.
__clrcallles pointeurs fonction sont uniquement destinés à être utilisés dans le domaine d'application dans lequel elles ont été créées.Au lieu de passage __clrcall pointeurs fonction entre domaines d'application, utilisez CrossAppDomainDelegate.Pour plus d'informations, consultez Domaines d'application et Visual C++.
Exemple
// clrcall.cpp
// compile with: /clr:oldSyntax /LD
void __clrcall Test1( ) {}
void (__clrcall *fpTest1)( ) = &Test1;
Notez que lorsqu'une fonction est déclarée avec __clrcall, code sera généré lorsque cela est nécessaire ; par exemple, lorsque fonction est appelée.
// 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();
}
L'exemple suivant montre que vous pouvez définir un pointeur fonction, telle que vous déclarez que le pointeur de fonction seulement sera appelé à partir du code managé.Cela permet au compilateur d'appeler directement la fonction managée et éviter le point d'entrée natif (problème de thunk double).
// clrcall3.cpp
// compile with: /clr
void Test() {
System::Console::WriteLine("in Test");
}
int main() {
void (*pTest)() = &Test;
(*pTest)();
void (__clrcall *pTest2)() = &Test;
(*pTest2)();
}