__clrcall
Указывает, что функцию можно вызвать только из управляемого кода. Используйте __clrcall для всех виртуальных функций, которые будут вызываться только из управляемого кода. Однако это соглашение о вызовах невозможно использовать для функций, которые будут вызываться из машинного кода. Модификатор __clrcall относится к Корпорации Майкрософт.
Используйте __clrcall для повышения производительности при вызове из управляемой функции в виртуальную управляемую функцию или из управляемой функции в управляемую функцию с помощью указателя.
Точки входа представляют собой отдельные функции, создаваемые компилятором. Если функция имеет машинные и управляемые точки входа, одна из них будет фактической функцией с реализацией функции. Другая функция будет отдельной функцией (преобразователем), которая вызывает фактическую функцию и позволяет среде CLR выполнять PInvoke. При маркировке функции как __clrcall необходимо указать, что реализация функции должна быть MSIL и что собственная функция точки входа не будет создана.
При получении адреса собственной функции, если __clrcall не указан, компилятор использует собственную точку входа. __clrcall указывает, что функция управляется, и нет необходимости проходить переход от управляемого к собственному. В этом случае компилятор использует управляемую точку входа.
Если /clr
используется (не /clr:pure
или /clr:safe
) и __clrcall не используется, принимая адрес функции всегда возвращает адрес собственной функции точки входа. При использовании __clrcall функция собственной точки входа не создается, поэтому вы получите адрес управляемой функции, а не функцию точки входа. Дополнительные сведения см. в разделе Double Thunking. Параметры компилятора /clr:pure и /clr:safe компилятора устарели в Visual Studio 2015 и не поддерживаются в Visual Studio 2017.
/clr (компиляция среды clr) подразумевает, что все функции и указатели функций __clrcall, и компилятор не позволит функции внутри компилятора пометить что-либо, отличное от __clrcall. Если используется параметр /clr:pure , __clrcall можно указать только в указателях функций и внешних объявлениях.
Вы можете напрямую вызывать функции __clrcall из существующего кода C++, скомпилированного с помощью /clr , если эта функция имеет реализацию MSIL. __clrcall функции нельзя вызывать непосредственно из функций, имеющих встроенные функции asm и вызывающие встроенные функции ЦП, например, даже если эти функции компилируются с /clr
помощью.
__clrcall указатели функций предназначены только для использования в домене приложения, в котором они были созданы. Вместо передачи указателей __clrcall функций в доменах приложений используйте CrossAppDomainDelegate. Дополнительные сведения см. в разделе "Домены приложений" и Visual C++.
Примеры
Обратите внимание, что при объявлении функции с __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();
}
in Func1
&Func1 != pf, comparison fails
in Func1
in Func1
В следующем примере показано, что можно определить указатель функции, например объявить, что указатель функции будет вызываться только из управляемого кода. Это позволит компилятору непосредственно вызвать управляемую функцию и избежать машинной точки входа (проблема двойного преобразования).
// clrcall3.cpp
// compile with: /clr
void Test() {
System::Console::WriteLine("in Test");
}
int main() {
void (*pTest)() = &Test;
(*pTest)();
void (__clrcall *pTest2)() = &Test;
(*pTest2)();
}
См. также
Передача аргументов и соглашения об именовании
Ключевые слова
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по