__clrcall__clrcall

Microsoft 固有の仕様Microsoft Specific

関数がマネージド コードからのみ呼び出されることを指定します。Specifies that a function can only be called from managed code. 使用 _ _clrcallのマネージ コードからのみ呼び出されるすべての仮想関数。Use __clrcall for all virtual functions that will only be called from managed code. ただし、この呼び出し規則は、ネイティブ コードから呼び出される関数には使用できません。However this calling convention cannot be used for functions that will be called from native code.

使用 _ _clrcall仮想マネージ関数をマネージ関数からまたはマネージ関数ポインターを通じてマネージ関数から呼び出すときにパフォーマンスを向上させる。Use __clrcall to improve performance when calling from a managed function to a virtual managed function or from managed function to managed function through pointer.

エントリ ポイントはコンパイラが生成した個別の関数です。Entry points are separate, compiler-generated functions. 関数にネイティブ エントリ ポイントとマネージド エントリ ポイントがある場合、そのいずれかが、関数実装を持つ実際の関数になります。If a function has both native and managed entry points, one of them will be the actual function with the function implementation. もう一方の関数は実際の関数に呼び出す別の関数 (サンク) で、共通言語ランタイムに PInvoke を実行させます。The other function will be a separate function (a thunk) that calls into the actual function and lets the common language runtime perform PInvoke. 関数としてマークするときに _ _clrcall関数の実装が MSIL にする必要があり、ネイティブ エントリ ポイント関数が生成されないことを示します。When marking a function as __clrcall, you indicate the function implementation must be MSIL and that the native entry point function will not be generated.

場合は、ネイティブ関数のアドレスを作成する際 _ _clrcallが指定されていない、コンパイラはネイティブ エントリ ポイントを使用します。When taking the address of a native function if __clrcall is not specified, the compiler uses the native entry point. _ _clrcall関数が管理されからの移行を経由する必要があるがネイティブに管理対象があることを示します。__clrcall indicates that the function is managed and there is no need to go through the transition from managed to native. その場合、コンパイラはマネージド エントリ ポイントを使用します。In that case the compiler uses the managed entry point.

ときに/clr(いない/clr:pureまたは/clr:safe) は使用と _ _clrcallは、ネイティブ エントリ ポイント関数のアドレスを返しますを使用しない関数のアドレスを常に取得します。When /clr (not /clr:pure or /clr:safe) is used and __clrcall is not used, taking the address of a function always returns the address of the native entry point function. ときに _ _clrcallが使用すると、ネイティブ エントリ ポイント関数は作成されず、いないエントリ ポイント サンク関数のマネージ関数のアドレスを取得するようにします。When __clrcall is used, the native entry point function is not created, so you get the address of the managed function, not an entry point thunk function. 詳細については、次を参照してください。ダブル サンキングします。For more information, see Double Thunking. /Clr: 純粋な/clr:safeコンパイラ オプションは Visual Studio 2015 で非推奨とされ、Visual Studio 2017 でサポートされていません。The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.

/clr (共通言語ランタイムのコンパイル)すべての関数と関数ポインターがあることを意味 _ _clrcall 以外のものとしてマークするコンパイル単位内の関数が許可されず、コンパイラと _ _clrcallします。/clr (Common Language Runtime Compilation) implies that all functions and function pointers are __clrcall and the compiler will not permit a function inside the compiland to be marked anything other than __clrcall. ときに /clr: 純粋なを使用する _ _clrcall関数ポインターと外部宣言でのみ指定できます。When /clr:pure is used, __clrcall can only be specified on function pointers and external declarations.

直接呼び出すことができます _ _clrcallから既存の関数C++を使用してコンパイルされたコード /clr限り、その関数がある MSIL を実装します。You can directly call __clrcall functions from existing C++ code that was compiled by using /clr as long as that function has an MSIL implementation. _ _clrcallでこれらの関数がコンパイルされた場合でも、関数をインライン asm を持ち CPU 固有の組み込み関数を呼び出すから直接関数を呼び出すことができません/clrします。__clrcall functions cannot be called directly from functions that have inline asm and call CPU-specific intrinisics, for example, even if those functions are compiled with /clr.

_ _clrcall関数ポインターが作成されたアプリケーション ドメインで使用するもののみです。__clrcall function pointers are only meant to be used in the application domain in which they were created. 渡すのではなく _ _clrcallアプリケーション ドメイン間で関数ポインターを使用してCrossAppDomainDelegateします。Instead of passing __clrcall function pointers across application domains, use CrossAppDomainDelegate. 詳細については、次を参照してください。アプリケーション ドメインと Visual cします。For more information, see Application Domains and Visual C++.

Example

関数を宣言するときに注意して _ _clrcall、必要なときにコードが生成されます。 関数が呼び出された場合などです。Note that when a function is declared with __clrcall, code will be generated when needed; for example, when function is called.

// 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

Example

次のサンプルでは、関数ポインターがマネージド コードからのみ呼び出されるように、関数ポインターを定義する方法を示します。The following sample shows that you can define a function pointer, such that, you declare that the function pointer will only be invoked from managed code. これにより、コンパイラはマネージド関数を直接呼び出し、ネイティブ エントリ ポイント (ダブル サンクの問題) を避けることができます。This allows the compiler to directly call the managed function and avoid the native entry point (double thunk issue).

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

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

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

関連項目See also

引数の渡し規則と名前付け規則Argument Passing and Naming Conventions
キーワードKeywords