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

참고 항목

인수 전달 및 명명 규칙
키워드