Поделиться через


__clrcall

Только для систем Microsoft

Указывает, что функция может вызываться только из управляемого кода.Использование __clrcall для всех виртуальных функций, которые будут вызываться только из управляемого кода.Однако это соглашение о вызовах не может использоваться для функций, которые будут вызываться из машинного кода.

Использование __clrcall для повышения производительности при вызове из управляемой функции виртуального управляемую функцию или управляемых функций через указатель управляемой функции.

Точки входа являются отдельные, созданный компилятором функции.Если обе точки входа неуправляемой и управляемой функции, один из них будет фактическая функция с реализацией функции.Другие функции будут отдельные функции (преобразователь), вызывает фактические функции и позволяет выполнять PInvoke среда CLR.Когда функция как __clrcall, указать реализацию функции должны быть MSIL и функцию точки входа в машинный код не будет создан.

При получении адреса функции в машинном коде, если __clrcall не указан, компилятор использует машинную точку входа.__clrcallУказывает, что управляемые функции и что нет необходимости выполнить переход из управляемого в машинный код.В этом случае компилятор использует управляемую точку входа.

При /clr (не /clr:pure или /clr:safe) используется и __clrcall — не используется, используя адрес функции всегда возвращает адрес функции точки входа в машинный код.При __clrcall — используется, функция точки входа в машинный код не создается, чтобы получить адрес управляемой функции не функцию точки входа в преобразователь.Дополнительные сведения см. в разделе Двойное преобразование (С++).

/clr (компиляция CLR)подразумевается, что все функции и указателей на функции, __clrcall и компилятор не позволяет функции внутри следует пометить ничего не __clrcall.При /clr:pure используется, __clrcall можно только на указатели функций и внешних объявлений.

Можно напрямую вызвать __clrcall функции из существующего кода C++, который был скомпилирован с помощью /clr до тех пор, пока функция имеет реализацию MSIL.__clrcallфункции нельзя вызывать напрямую из функции, которые имеют встроенные asm и вызвать intrinisics ЦП, например, даже в том случае, если эти функции компилируются с /clr.

__clrcallуказатели на функции только предназначен для использования в домене приложения, в котором они были созданы.Вместо передачи __clrcall указатели функций между доменами приложения, используйте CrossAppDomainDelegate.Дополнительные сведения см. в разделе Домены приложений и Visual C++.

Пример

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

Обратите внимание, что при объявлении функции с __clrcall, будет создан код, при необходимости; Например, при вызове функции.

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

В следующем примере показано, что можно определить указатель на функцию, таким образом, что объявить, что указатель функции будет вызываться только из управляемого кода.Это позволяет компилятору напрямую вызывать управляемые функции и избежать машинную точку входа (double преобразователь проблема).

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

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

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

См. также

Ссылки

Передача и соглашения об именовании аргумента

Ключевые слова C++