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