__clrcall
관리 코드에서만 함수를 호출할 수 있도록 지정합니다. 관리 코드에서만 호출되는 모든 가상 함수에 __clrcall 사용합니다. 그러나 네이티브 코드에서 호출되는 함수에는 이 호출 규칙을 사용할 수 없습니다. __clrcall 한정자는 Microsoft 전용입니다.
__clrcall 사용하여 관리되는 함수에서 가상 관리 함수로 호출하거나 관리되는 함수에서 포인터를 통해 관리되는 함수로 호출할 때 성능을 향상시킵니다.
진입점은 컴파일러에서 생성된 별도의 함수입니다. 함수에 네이티브 진입점과 관리되는 진입점이 둘 다 있을 경우 둘 중 하나는 함수 구현이 포함된 실제 함수입니다. 다른 함수는 실제 함수를 호출하고 공용 언어 런타임에서 PInvoke를 수행하게 하는 별도의 함수(썽크)입니다. 함수 를 __clrcall 표시할 때 함수 구현이 MSIL이어야 하며 네이티브 진입점 함수가 생성되지 않음을 나타냅니다.
__clrcall 지정되지 않은 경우 네이티브 함수의 주소를 사용하는 경우 컴파일러는 네이티브 진입점을 사용합니다. __clrcall 함수가 관리되며 관리되는 함수에서 네이티브로 전환할 필요가 없음을 나타냅니다. 이 경우 컴파일러가 관리되는 진입점을 사용합니다.
(사용 안 /clr:pure
됨 또는/clr:safe
)이 사용되고 __clrcall 사용되지 않는 경우 /clr
함수의 주소를 사용하면 항상 네이티브 진입점 함수의 주소가 반환됩니다. __clrcall 사용하면 네이티브 진입점 함수가 만들어지지 않으므로 진입점 펑크 함수가 아닌 관리되는 함수의 주소를 가져옵니다. 자세한 내용은 Double Thunking을 참조 하세요. /clr:pure 및 /clr:safe 컴파일러 옵션은 Visual Studio 2015에서 더 이상 사용되지 않으며 Visual Studio 2017에서는 지원되지 않습니다.
/clr(공용 언어 런타임 컴파일)은 모든 함수 및 함수 포인터가 __clrcall 컴파일러에서 컴파일러 내의 함수가 __clrcall 이외의 것으로 표시되도록 허용하지 않음을 의미합니다. /clr:pure를 사용하는 경우 함수 포인터 및 외부 선언에서만 __clrcall 지정할 수 있습니다.
해당 함수에 MSIL 구현이 있는 한 /clr을 사용하여 컴파일된 기존 C++ 코드에서 __clrcall 함수를 직접 호출 할 수 있습니다. __clrcall 함수는 인라인 asm이 있고 CPU 관련 내장 함수를 호출하는 함수에서 직접 호출할 수 없습니다(예: 해당 함수가 컴파일된 /clr
경우에도).
__clrcall 함수 포인터는 애플리케이션 do기본 생성에서만 사용됩니다. 애플리케이션에서 __clrcall 함수 포인터를 전달하는 대신 기본 사용합니다CrossAppDomainDelegate. 자세한 내용은 Application Do기본 및 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 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기