マネージド コードとアンマネージド コードの相互運用性の概要
ソニャ・ケゼロヴィッチ プログラムマネージャー
David Mortenson、リード ソフトウェア デザイン エンジニア
Adam Nathan、テストのリード ソフトウェア 設計エンジニア
Microsoft Corporation
2003 年 10 月
適用対象:
Microsoft® .NET Framework
COM 相互運用機能
の概要: この記事では、マネージド コードとアンマネージド コード間の相互運用性に関する基本的な事実、およびマネージド コードからアンマネージ API にアクセスしてラップしたり、マネージド API をアンマネージ呼び出し元に公開したりするためのガイドラインと一般的なプラクティスについて説明します。 セキュリティと信頼性に関する考慮事項、パフォーマンス データ、開発プロセスの一般的なプラクティスも強調表示されています。 (14ページ印刷)
前提条件: このドキュメントの対象ユーザーには、マネージド コードを使用する場所に関する大まかな決定を行う必要がある開発者とマネージャーが含まれます。 そのためには、マネージド コードとアンマネージド コード間の相互作用のしくみと、現在のガイドラインが特定のシナリオにどのように適用されるかを理解すると役立ちます。
内容
相互運用性の概要
相互運用性のガイドライン
安全
確実
パフォーマンス
付録 1: 相互運用性の境界を越える
付録 2: リソース
付録 3: 用語集
相互運用性の概要
共通言語ランタイム (CLR) は、マネージ コードと COM コンポーネント、COM+ サービス、Win32® API、およびその他の種類のアンマネージ コードとの対話を促進します。 データ型、エラー処理メカニズム、作成と破棄の規則、および設計ガイドラインは、マネージド オブジェクト モデルとアンマネージド オブジェクト モデルによって異なります。 マネージド コードとアンマネージド コード間の相互運用を簡略化し、移行パスを容易にするために、CLR 相互運用レイヤーでは、クライアントとサーバーの両方からこれらのオブジェクト モデル間の違いを隠します。
相互運用性 ("相互運用") は双方向であるため、次のことが可能になります。
マネージド コードからアンマネージ API を呼び出す
これは、フラット API (kernel32.dll や user32.dllなどの DLL から公開される Win32 API などの静的 DLL エクスポート) と COM API (Microsoft® Word、Excel、Internet Explorer、ActiveX® データ オブジェクト (ADO) によって公開されるオブジェクト モデルなど) の両方に対して実行できます。
マネージド API をアンマネージ コード に公開する
これを行う例としては、Windows Media® Player などの COM ベースのアプリケーション用のアドインの作成や、MFC フォームへのマネージド Windows フォーム コントロールの埋め込みなどがあります。
次の 3 つの補完的なテクノロジにより、次のマネージド/アンマネージド操作が可能になります。
- プラットフォーム呼び出し (P/Invoke とも呼ばれます) を使用すると、マネージド ソース コードでシグネチャが再宣言されている限り、アンマネージ言語で任意の関数を呼び出すことができます。 これは、Visual Basic® 6.0 の
Declare
ステートメントによって提供された機能に似ています。 - COM 相互運用機能を使用すると、通常のマネージド コンポーネントの使用と同様の方法で、任意のマネージド言語で COM コンポーネントを呼び出すことができます。その逆も同様です。 COM 相互運用機能は、CLR によって提供されるコア サービスと、System.Runtime.InteropServices 名前空間内のいくつかのツールと API で構成されます。
- C++ 相互運用機能 (It Just Works (IJW) とも呼ばれます) は C++ 固有の機能であり、フラット API と COM API は常に使用されているため、直接使用できます。 これは COM 相互運用機能よりも強力ですが、より多くの注意が必要です。 このテクノロジを使用する前に、必ず C++ リソースを確認してください。
相互運用性のガイドライン
マネージド コードからのアンマネージ API の呼び出し
アンマネージド API にはいくつかの種類があり、それらを呼び出すための相互運用テクノロジにはいくつかの種類があります。 これらのテクノロジを使用する方法とタイミングに関する推奨事項については、このセクションで説明します。 これらの提案は非常に一般的であり、すべてのシナリオをカバーしているわけではないことに注意してください。 シナリオを慎重に評価し、シナリオに適した開発プラクティスやソリューションを適用する必要があります。
アンマネージ フラット API の呼び出し
マネージド コードからアンマネージド フラット API を呼び出すには、プラットフォーム呼び出し (すべてのマネージド言語で利用可能) または C++ 相互運用 (C++ で利用可能) の 2 つのメカニズムがあります。
これらの相互運用テクノロジのいずれかを使用してフラット API を呼び出す前に、.NET Framework で使用できる同等の機能があるかどうかを判断する必要があります。 可能な限り、アンマネージ API を呼び出す代わりに .NET Framework 機能を使用することをお勧めします。
いくつかのアンマネージ メソッドのみを呼び出す場合や単純なフラット API を呼び出す場合は、C++ 相互運用機能の代わりにプラットフォーム呼び出しを使用することをお勧めします。 単純なフラット API のプラットフォーム呼び出し宣言の記述は簡単です。 CLR は、DLL の読み込みとすべてのパラメーター マーシャリングを処理します。 複雑なフラット API に対していくつかのプラットフォーム呼び出し宣言を記述する作業であっても、C++ 相互運用機能を使用し、C++ で記述されたまったく新しいモジュールを導入するコストと比べると、ごくわずかです。
複雑なアンマネージ フラット API をラップする場合、またはマネージド コードの開発中に変更されるアンマネージ フラット API をラップする場合は、プラットフォーム呼び出しの代わりに C++ 相互運用機能を使用することをお勧めします。 C++ レイヤーは非常に薄く、残りのマネージド コードは任意の他のマネージド言語で記述できます。 これらのシナリオでプラットフォーム呼び出しを使用するには、マネージド コードで API の複雑な部分を再宣言し、アンマネージド API と同期させるために多くの労力が必要になります。 C++ 相互運用機能を使用すると、アンマネージ API への直接アクセスを許可することでこの問題が解決されます。これは、書き換える必要がなく、ヘッダー ファイルを含めるだけで済みます。
COM API の呼び出し
マネージド コードから COM コンポーネントを呼び出すには、COM 相互運用機能 (すべてのマネージド言語で利用可能) または C++ 相互運用 (C++ で利用可能) の 2 つの方法があります。
OLE オートメーション互換 COM コンポーネントを呼び出す場合は、COM 相互運用機能を使用することを推奨します。 CLR は、COM コンポーネントのアクティブ化とパラメーター マーシャリングを処理します。
インターフェイス定義言語 (IDL) に基づいて COM コンポーネントを呼び出す場合は、C++ 相互運用機能を使用することを推奨します。 C++ レイヤーは非常に薄く、残りのマネージド コードは任意のマネージド言語で記述できます。 COM 相互運用機能は、タイプ ライブラリからの情報に依存して正しい相互運用呼び出しを行いますが、通常、タイプ ライブラリには IDL ファイルに存在するすべての情報が含まれているわけではありません。 C++ 相互運用機能を使用すると、これらの COM API に直接アクセスできるため、この問題が解決されます。
既に出荷済みの COM API を所有する企業の場合は、これらの API のプライマリ相互運用機能アセンブリ (PIA) を出荷することを検討することが重要です。そのため、マネージド クライアントで簡単に使用できます。
アンマネージ API を呼び出すためのデシジョン ツリー
図 1. アンマネージ API のデシジョン ツリーの呼び出し
マネージド API をアンマネージ コードに公開する
マネージド API を純粋にアンマネージ呼び出し元に公開するには、COM API とフラット API の 2 つの主な方法があります。 Visual Studio® .NET を使用してコードを再コンパイルする C++ アンマネージド クライアントの場合、3 つ目のオプションとして、C++ 相互運用を介してマネージド機能に直接アクセスする方法があります。 これらのオプションを使用する方法とタイミングについては、このセクションで説明します。
マネージド API に直接アクセスする
アンマネージド クライアントが C++ で記述されている場合は、Visual Studio .NET C++ コンパイラで "混合モード イメージ" としてコンパイルできます。これが完了すると、アンマネージド クライアントは任意のマネージド API に直接アクセスできます。 ただし、一部のコーディング規則は、アンマネージ コードからマネージド オブジェクトにアクセスする場合に適用されます。詳細については、C++ のドキュメントを参照してください。
直接アクセスは、マネージド API 開発者からの特別な考慮事項を必要としないため、推奨されるオプションです。 マネージド API 設計ガイドライン (DG) に従ってマネージド API を設計し、アンマネージド呼び出し元が API に引き続きアクセスできることを確信できます。
マネージ API を COM API として公開する
すべてのパブリック マネージド クラスは、COM 相互運用機能を使用してアンマネージド クライアントに公開できます。 COM 相互運用層がすべての COM 配管を処理するため、このプロセスは実装が非常に簡単です。 したがって、たとえば、すべてのマネージド クラスは、IUnknown、
マネージド API を COM API として公開するのは簡単ですが、マネージド オブジェクト モデルと COM オブジェクト モデルは大きく異なります。 そのため、マネージ API を COM に公開することは、常に明示的な設計上の決定である必要があります。 マネージド ワールドで使用できる一部の機能は、COM の世界では同等ではなく、COM クライアントからは使用できません。 このため、多くの場合、マネージド API 設計ガイドライン (DG) と COM との互換性には緊張があります。
COM クライアントが重要な場合は、マネージド API の設計ガイドラインに従ってマネージド API を記述し、COM に公開されるマネージド API の周囲に、COM に対応した細いマネージド ラッパーを記述します。
マネージド API をフラット API として公開する
アンマネージ クライアントが COM を使用できない場合があります。 たとえば、フラット API を使用するように既に記述されており、変更または再コンパイルできない場合があります。 C++ は、マネージド API をフラット API として公開できる唯一の高度な言語です。 これを行うことは、マネージド API を COM API として公開するほど簡単ではありません。 これは、C++ 相互運用に関する高度な知識と、マネージド ワールドとアンマネージド ワールドの違いを必要とする、非常に高度な手法です。
必要な場合にのみ、マネージド API をフラット API として公開します。 選択肢がない場合は、必ず C++ のドキュメントを確認し、すべての制限事項を十分に認識してください。
マネージド API を公開するためのデシジョン ツリー
図 2. マネージド API デシジョン ツリーの公開
安全
共通言語ランタイムには、アセンブリの原点に関する情報に基づいて保護されたリソースへのアクセスを規制するセキュリティ システム Code Access Security (CAS) が付属しています。 アンマネージ コードを呼び出すと、大きなセキュリティ リスクが伴います。 適切なセキュリティ チェックがないと、アンマネージ コードは CLR プロセス内のマネージド アプリケーションの任意の状態を操作できます。 また、これらのリソースが CAS アクセス許可チェックの対象とならなくても、アンマネージ コード内のリソースを直接呼び出すこともできます。 そのため、アンマネージ コードへの移行は高度に保護された操作と見なされ、セキュリティ チェックを含める必要があります。 このセキュリティ チェックでは、アンマネージド コードの遷移を含むアセンブリと、それを呼び出すすべてのアセンブリが、アンマネージ コードを実際に呼び出す権限を持っている必要があるアンマネージ コードのアクセス許可を検索します。
完全なセキュリティ チェックが不要であり、コンポーネントのパフォーマンスまたはスコープを過度に制限する、制限付きの相互運用シナリオがいくつかあります。 これは、アンマネージ コードから公開されるリソースにセキュリティ関連がない場合 (システム時刻、ウィンドウ座標など)、またはリソースがアセンブリ内でのみ使用され、任意の呼び出し元にパブリックに公開されていない場合です。 このような場合は、関連する API のすべての呼び出し元に対するアンマネージ コードアクセス許可の完全なセキュリティ チェックを抑制できます。 これを行うには、SuppressUnmanagedCodeSecurity カスタム属性をそれぞれの相互運用メソッドまたはクラスに適用します。 これは、部分的に信頼されたコードがそのような API を悪用できないと判断した慎重なセキュリティ レビューを前提とします。
確実
マネージド コードは、アンマネージド コードよりも信頼性が高く堅牢に設計されています。 これらの特性を促進する CLR 機能の 1 つの例として、メモリ リークを防ぐために未使用のメモリを解放するガベージ コレクションがあります。 もう 1 つの例として、マネージド 型セーフがあります。これは、バッファー オーバーランの間違いや他の型関連エラーを防ぐために使用されます。
任意の種類の相互運用テクノロジを使用する場合、コードは純粋なマネージド コードほど信頼性が高くないか、堅牢でない可能性があります。 たとえば、アンマネージド メモリを手動で割り当て、操作が完了したら解放することを忘れないでください。
非自明な相互運用コードを記述するには、アンマネージド コードの記述と同じ信頼性と堅牢性に注意する必要があります。 すべての相互運用コードが正しく記述されている場合でも、システムはアンマネージド パーツと同じくらい信頼性が高くなります。
パフォーマンス
マネージド コードからアンマネージド コード (およびその逆) に移行するたびに、パフォーマンスのオーバーヘッドが発生します。 オーバーヘッドの量は、使用されるパラメーターの種類によって異なります。 CLR 相互運用レイヤーでは、遷移の種類とパラメーターの種類に基づいて、Just-In-Time (JIT) インライン化、コンパイル済みアセンブリ スタブ、および解釈されたマーシャリング スタブ (最も高速から低速の呼び出しの順) に基づいて、3 つのレベルの相互運用呼び出しの最適化が使用されます。
プラットフォーム呼び出しのおおよそのオーバーヘッド: 10 台のマシン命令 (x86 プロセッサ)
COM 相互運用機能呼び出しのおおよそのオーバーヘッド: 50 台のマシン命令 (x86 プロセッサ)
これらの手順の作業は、「フラット API の呼び出し: ステップ バイ ステップ」および「COM API の呼び出し: ステップ バイ ステップ」の付録セクションに示されています。 呼び出し中にガベージ コレクターがアンマネージ スレッドをブロックしないようにし、呼び出し規則とアンマネージ例外を処理するだけでなく、現在のランタイム呼び出し可能ラッパー (RCW) の呼び出しを現在のコンテキストに適した COM インターフェイス ポインターに変換するための追加の作業が COM 相互運用機能によって行われます。
相互運用呼び出しのたびに、いくつかのオーバーヘッドが発生します。 これらの呼び出しが発生する頻度と、メソッド実装内で発生する作業の重要性に応じて、呼び出しごとのオーバーヘッドはごくわずかから非常に顕著なものまでさまざまです。
これらの考慮事項に基づいて、次の一覧に役立つ可能性がある一般的なパフォーマンスに関する推奨事項を示します。
マネージド コードとアンマネージド コードの間のインターフェイスを制御する場合は、"chatty" ではなく "チャンク" にして、遷移の合計数を減らします。
チャットインターフェイスは、相互運用境界の反対側で重要な作業を行うことなく、多くの遷移を行うインターフェイスです。 たとえば、プロパティセッターとゲッターはおしゃべりです。 チャンク インターフェイスは、いくつかの遷移のみを行うインターフェイスであり、境界の反対側で実行される作業の量は重要です。 たとえば、データベース接続を開き、一部のデータを取得するメソッドはチャンクです。 チャンク インターフェイスでは、相互運用の移行が少なくなっています。そのため、パフォーマンスのオーバーヘッドを排除できます。
可能であれば、Unicode/ANSI 変換は避けてください。
Unicode から ANSI またはその逆の文字列の変換は、コストのかかる操作です。 たとえば、文字列を渡す必要があるが、その内容が重要でない場合は、IntPtr として文字列パラメーターを宣言でき、相互運用マーシャラーは変換を行いません。
高パフォーマンスのシナリオでは、パラメーターとフィールドを IntPtr
として宣言すると、使いやすさと保守容易性を犠牲にしながらも、パフォーマンスが向上する可能性があります。 既定の相互運用マーシャリングに依存するのではなく、Marshal クラスで使用できるメソッドを使用して手動マーシャリングを実行する方が高速な場合があります。 たとえば、大きな文字列の配列を相互運用境界を越えて渡す必要があるが、必要な要素が少ない場合は、配列を IntPtr として宣言し、それらの少数の要素にのみ手動でアクセスする方がはるかに高速になります。
InAttribute を使用し、outAttribute を賢明にして、不要なマーシャリングを減らします。 相互運用マーシャラーは、呼び出しの前に特定のパラメーターをマーシャリングし、呼び出し後にマーシャリングする必要があるかどうかを判断するときに、既定の規則を使用します。 これらのルールは、間接参照のレベルとパラメーターの型に基づいています。 これらの操作の一部は、メソッドのセマンティクスによっては必要ない場合があります。
プラットフォーム呼び出しシグネチャ
SetLastError=false を使用するのは、後で marshal.GetLastWin32Error呼び出す場合のみです。 プラットフォーム呼び出しシグネチャ SetLastError=true を設定するには、最後のエラー コードを保持するために相互運用レイヤーからの追加作業が必要です。 この機能は、この情報に依存し、通話後に使用する場合にのみ使用します。
アンマネージド呼び出しが悪用不可能な方法で公開されている場合にのみ、SuppressUnmanagedCodeSecurityAttribute を使用してセキュリティ チェックの数を減らします。
セキュリティ チェックは非常に重要です。 API が保護されたリソースや機密情報を公開していない場合、または適切に保護されている場合は、広範なセキュリティ チェックによって不要なオーバーヘッドが発生する可能性があります。 ただし、セキュリティ チェックを行わないコストは非常に高くなります。
付録 1: 相互運用性の境界を越える
Flat API の呼び出し: ステップ バイ ステップ
図 3. フラット API の呼び出し
- LoadLibrary
取得し、GetProcAddressを します。 - ターゲット アドレスを含む署名から DllImport スタブを作成します。
- 呼び出し先で保存されたレジスタをプッシュします。
- DllImport フレームを設定し、フレームのスタックにプッシュします。
- 一時メモリが割り当てられている場合は、呼び出しが完了したときに迅速に解放されるようにクリーンアップ リストを初期化します。
- パラメーターをマーシャリングします。 (これによりメモリが割り当てられる可能性があります)。)
- ガベージ コレクション モードを協調モードからプリエンプティブモードに変更して、ガベージ コレクションをいつでも実行できるようにします。
- ターゲット アドレスを読み込んで呼び出します。
- SetLastError ビット
設定されている場合は、GetLastError 呼び出し、スレッド ローカル ストレージに格納されたスレッド抽象化に結果を格納します。 - 協調ガベージ コレクション モードに戻ります。
- PreserveSig=false
し、メソッドがエラー HRESULT を返した場合は、例外をスローします。 - 例外がスローされなかった場合は、
をバックプロパゲートし、ref による パラメーターを します。 - 呼び出し元のポップされた引数を考慮して、拡張スタック ポインターを元の値に復元します。
COM API の呼び出し: ステップ バイ ステップ
図 4. COM API の呼び出し
- シグネチャからマネージドからアンマネージド スタブを構築します。
- 呼び出し先で保存されたレジスタをプッシュします。
- マネージドからアンマネージドの COM 相互運用フレームを設定し、フレームのスタックにプッシュします。
- 移行中に使用される一時データの領域を予約します。
- 一時メモリが割り当てられている場合は、呼び出しが完了したときに迅速に解放されるようにクリーンアップ リストを初期化します。
- 浮動小数点例外フラグをクリアします (x86 のみ)。
- パラメーターをマーシャリングします。 (これによりメモリが割り当てられる可能性があります)。)
- ランタイム呼び出し可能ラッパー内の現在のコンテキストの正しいインターフェイス ポインターを取得します。 キャッシュされたポインターを使用できない場合は、COM コンポーネントで QueryInterface を呼び出して取得します。
- ガベージ コレクション モードを協調モードからプリエンプティブモードに変更して、ガベージ コレクションをいつでも実行できるようにします。
- vtable ポインターから、スロット番号でインデックスを付け、ターゲット アドレスを取得して呼び出します。
- QueryInterface が以前に呼び出された場合は、インターフェイス ポインター Release を呼び出します。
- 協調ガベージ コレクション モードに戻ります。
- 署名が PreserveSig
マークされていない場合は、エラー HRESULT を確認し、例外をスローします (IErrorInfo 情報 入力されている可能性があります)。 - 例外がスローされなかった場合は、
をバックプロパゲートし、ref による パラメーターを します。 - 呼び出し元がポップした引数を考慮して、拡張スタック ポインターを元の値に復元します。
COM からのマネージド API の呼び出し: ステップ バイ ステップ
図 5. COM からのマネージド API の呼び出し
- シグネチャからアンマネージドからマネージドスタブを構築します。
- 呼び出し先で保存されたレジスタをプッシュします。
- アンマネージからマネージドへの COM 相互運用フレームを設定し、フレームのスタックにプッシュします。
- 移行中に使用される一時データの領域を予約します。
- ガベージ コレクション モードを協調モードからプリエンプティブモードに変更して、ガベージ コレクションをいつでも実行できるようにします。
- インターフェイス ポインターから COM 呼び出し可能ラッパー (CCW) を取得します。
- CCW 内のマネージド オブジェクトを取得します。
- 必要に応じて、appdomains を移行します。
- appdomain に完全な信頼がない場合は、メソッドがターゲット appdomain に対して持つ可能性のあるリンク要求を実行します。
- 一時メモリが割り当てられている場合は、呼び出しが完了したときに迅速に解放されるようにクリーンアップ リストを初期化します。
- パラメーターをマーシャリングします。 (これによりメモリが割り当てられる可能性があります)。)
- 呼び出すターゲットマネージド メソッドを見つけます。 (これには、ターゲット実装へのインターフェイス呼び出しのマッピングが含まれます)。
- 戻り値をキャッシュします。 (浮動小数点の戻り値の場合は、浮動小数点レジスタから取得します)。
- 協調ガベージ コレクション モードに戻ります。
- 例外がスローされた場合は、返す HRESULT を抽出し、SetErrorInfo
呼び出します。 - 例外がスローされなかった場合は、
をバックプロパゲートし、ref による パラメーターを します。 - 呼び出し元がポップした引数を考慮して、拡張スタック ポインターを元の値に復元します。
付録 2: リソース
必読!.NET と COM: Adam Nathan による完全な相互運用性ガイド
アンマネージ コードとの相互運用
相互運用機能のサンプル、Microsoft .NET Framework
Adam Nathan の ブログ
Chris Brumme の ブログ
付録 3: 用語集
AppDomain (アプリケーション ドメイン) | アプリケーション ドメインは軽量の OS プロセスと似ていると見なすことができ、共通言語ランタイムによって管理されます。 |
CCW (COM 呼び出し可能ラッパー) | COM コードからアクティブ化されたマネージド オブジェクトの周囲に CLR 相互運用レイヤーによって作成される特別な種類のラッパー。 CCW は、データ マーシャリング、有効期間管理、ID 管理、エラー処理、適切なアパートメントとスレッドの遷移などを提供することで、マネージド オブジェクト モデルと COM オブジェクト モデルの違いを隠します。 CCW は、マネージド コードの実装者が COM プラミングについて何も知らなくても、COM フレンドリな方法でマネージド オブジェクト機能を公開します。 |
CLR | 共通言語ランタイム。 |
COM 相互運用機能 | マネージド コードから COM API を使用したり、マネージド API を COM API としてアンマネージ クライアントに公開したりするために、CLR 相互運用レイヤーによって提供されるサービス。 COM 相互運用機能は、すべてのマネージド言語で使用できます。 |
C++ 相互運用機能 | C++ 言語コンパイラと CLR によって提供されるサービスは、マネージド コードとアンマネージド コードを同じ実行可能ファイルに直接混在するために使用されます。 C++ 相互運用には、通常、アンマネージ API にヘッダー ファイルを含め、特定のコーディング規則に従う必要があります。 |
Complex フラット API | マネージド言語で宣言するのが難しいシグネチャを持つ API。 たとえば、可変サイズの構造体パラメーターを持つメソッドは、マネージド型システムに同等の概念がないため、宣言が困難です。 |
相互運用機能 | マネージド コードとアンマネージド コード ("ネイティブ" とも呼ばれます) の間の相互運用性の任意の種類を対象とする一般的な用語。 相互運用機能は、CLR によって提供される多くのサービスの 1 つです。 |
相互運用機能アセンブリ | タイプ ライブラリに含まれる COM 型に相当するマネージド型を含む特殊な型のマネージド アセンブリ。 通常、タイプ ライブラリ インポーター ツール (Tlbimp.exe) をタイプ ライブラリで実行することによって生成されます。 |
マネージド コードの | CLR の制御下で実行されるコードは、マネージド コードと呼ばれます。 たとえば、C# または Visual Basic .NET で記述されたコードはマネージド コードです。 |
プラットフォーム呼び出し | マネージド コードからアンマネージ フラット API を呼び出すための CLR 相互運用レイヤーによって提供されるサービス。 プラットフォーム呼び出しは、すべてのマネージド言語で使用できます。 |
RCW (ランタイム呼び出し可能な wapper) | マネージド コードからアクティブ化される COM オブジェクトの周囲に CLR 相互運用レイヤーによって作成される特別な種類のラッパー。 RCW は、データ マーシャリング、有効期間管理、ID 管理、エラー処理、適切なアパートメントとスレッドの遷移などを提供することで、マネージド オブジェクト モデルと COM オブジェクト モデルの違いを隠します。 |
アンマネージ コードの | CLR の外部で実行されるコードは、"アンマネージ コード" と呼ばれます。COM コンポーネント、ActiveX コンポーネント、および Win32 API 関数は、アンマネージ コードの例です。 |