__clrcall
Programu Microsoft
Określa, że funkcja może być wywoływana tylko z kodu zarządzanego.Użyj __clrcall dla wszystkich funkcji wirtualnych, które zostanie wywołana tylko z kodu zarządzanego.Jednakże niniejszej konwencji wywoływania nie można użyć funkcji, które zostanie wywołana z kodem macierzystym.
Użyj __clrcall do poprawy wydajności podczas wywoływania z zarządzanych funkcji wirtualnych zarządzanych funkcji lub funkcja zarządzanych funkcji zarządzanych przez wskaźnik.
Punkty wejścia są funkcje oddzielnych, generowanych przez kompilator.Jeśli funkcja ma zarówno punkty wejścia macierzystych i zarządzanych, jeden z nich będzie rzeczywistej funkcji z implementacją funkcji.Inne funkcje będą oddzielne funkcji (thunk), która wzywa do rzeczywistej funkcji i umożliwia wykonywanie funkcji PInvoke common language runtime.Gdy znakowanie funkcji jako __clrcall, wskazać implementacji funkcji musi być MSIL i funkcji punktu wejścia macierzysty nie zostanie wygenerowany.
Przy podejmowaniu adres funkcji macierzystego, jeżeli __clrcall nie jest określony, kompilator używa punktu wejścia macierzystym.__clrcallWskazuje, że funkcja jest zarządzany i istnieje potrzeba przejść przez przejście z zarządzanych macierzystą.W takim przypadku kompilator używa punktu wejścia zarządzanych.
Gdy /clr (nie /clr:pure lub /clr:safe) jest używany i __clrcall jest nie jest używany, biorąc pod adres funkcji zawsze zwraca adres funkcji punktu wejścia macierzystym.Gdy __clrcall jest używany, funkcji punktu wejścia macierzysty nie jest tworzony, aby uzyskać adres funkcji zarządzanych, nie funkcji punktu wejścia thunk.Aby uzyskać więcej informacji, zobacz Podwójne pośredniczeniem (C++).
/ CLR (kompilacja wspólnej Language Runtime)zakłada się, że wszystkie funkcje i wskaźników funkcji są __clrcall i kompilator nie pozwolą funkcji wewnątrz compiland być oznaczone cokolwiek innego niż __clrcall.Gdy /clr:pure jest używana, __clrcall można określić tylko w sprawie deklaracji zewnętrznych i wskaźników funkcji.
Można bezpośrednio wywołać __clrcall funkcji z istniejących kodu C++, który został skompilowany przy użyciu /clr tak długo, jak ta funkcja ma implementację MSIL.__clrcallnie można wywołać funkcji bezpośrednio z funkcji, które mają wbudowane asm i wywołać intrinisics specyficzne dla Procesora, na przykład, nawet jeśli te funkcje są opracowywane z /clr.
__clrcalltylko wskaźników funkcji mają być używane do domeny aplikacji, w którym zostały utworzone.Zamiast przekazywanie __clrcall działać wskaźniki domenach aplikacji, użyj CrossAppDomainDelegate.Aby uzyskać więcej informacji, zobacz Domen aplikacji i Visual C++.
Przykład
// clrcall.cpp
// compile with: /clr:oldSyntax /LD
void __clrcall Test1( ) {}
void (__clrcall *fpTest1)( ) = &Test1;
Należy zauważyć, że gdy funkcja zadeklarowana ze __clrcall, kod zostanie wygenerowany, gdy są potrzebne; na przykład, gdy wywoływana jest funkcja.
// 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();
}
Poniżej przedstawiono przykładowe że wskaźnik funkcji, można zdefiniować tak, aby zadeklarować, że wskaźnik funkcji tylko zostanie wywołany z kodu zarządzanego.Umożliwia to kompilator bezpośrednio wywołać funkcję zarządzanych i uniknięcia punktu wejścia macierzysty (problem podwójnego thunk).
// clrcall3.cpp
// compile with: /clr
void Test() {
System::Console::WriteLine("in Test");
}
int main() {
void (*pTest)() = &Test;
(*pTest)();
void (__clrcall *pTest2)() = &Test;
(*pTest2)();
}