Udostępnij za pośrednictwem


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

Zobacz też

Informacje

Argument, przekazując i konwencji nazewnictwa

Słów kluczowych języka C++