共用方式為


__clrcall

Microsoft 專有的

指定只可以從 managed 程式碼呼叫函式。 使用__clrcall才會從 managed 程式碼呼叫的所有虛擬函式。 不過這個呼叫慣例不能用於將會從原生程式碼呼叫的函式。

使用__clrcall來從受管理的函式,以虛擬的 managed 函式或受管理的函式透過指標的 managed 函式呼叫時改善效能。

進入點都是個別的編譯器所產生的函式。 如果函式具有兩個原生和 managed 進入點,另一個設定為將會與函式實作實際的函式。 此函式會好個別函式 (thunk),執行實際的函式呼叫,並可讓執行 PInvoke common language runtime。 在標記為函式時__clrcall,您指定的函式實作必須是 MSIL 和原生進入點函式將不會產生。

當取得原生函式的位址,如果__clrcall未指定,則編譯器會使用原生進入點。 __clrcall表示函式的管理,而且沒有經過來回轉換不需要管理到原生。 在此情況下編譯器會使用受管理的進入點。

當**/clr** (不**/clr:pure/clr:safe**) 會使用與__clrcall是未使用,會永遠花費函式的位址傳回原生進入點函式的位址。 當__clrcall是使用,原生進入點函式不會建立,因而提供您的 managed 函式沒有進入點函 thunk 式的位址。 如需詳細資訊,請參閱 Double Thunking (C++)

/clr (Common Language Runtime 編譯)所示所有的函式和函式指標都是__clrcall ,並且編譯器不允許函式內部的標記的任何項目而非編譯__clrcall。 當**/clr:pure** , __clrcall只能在函式指標和外部宣告上指定。

您可以直接呼叫__clrcall函式從現有的 C++ 程式碼編譯藉由使用**/clr** ,只要該函數語法包含有 MSIL 實作。 __clrcall不能直接從內嵌 asm,比方說,呼叫特定 CPU 的 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();
}
  

下列範例會顯示您可以定義函式指標,以致您宣告的函式指標只會叫用的 managed 程式碼。 這可讓編譯器直接呼叫 managed 函式,並避免原生進入點 (雙精度浮點的 thunk 問題)。

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

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

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

請參閱

參考

引數傳遞,和命名慣例

C + + 關鍵字