相互運用マーシャリングは、メソッド引数でデータを渡す方法と、呼び出し中にマネージド メモリとアンマネージド メモリの間で値を返す方法を制御します。 相互運用マーシャリングは、共通言語ランタイムのマーシャリング サービスによって実行されるランタイム アクティビティです。
ほとんどのデータ型は、マネージド メモリとアンマネージド メモリの両方で共通の表現を持っています。 相互運用マーシャラーは、これらの型を処理します。 その他の型は、あいまいであるか、マネージド メモリ内でまったく表されない場合があります。
あいまいな型には、1 つのマネージド型にマップされる複数のアンマネージ表現、または配列のサイズなどの型情報がない場合があります。 あいまいな型の場合、マーシャラーは既定の表現と、複数の表現が存在する代替表現を提供します。 マーシャラーに対して、あいまいな型をマーシャリングする方法について明示的な命令を指定できます。
プラットフォーム呼び出しと COM 相互運用モデル
共通言語ランタイムには、アンマネージ コードと相互運用するための 2 つのメカニズムが用意されています。
- プラットフォーム呼び出し。マネージド コードがアンマネージ ライブラリからエクスポートされた関数を呼び出すことができます。
- COM 相互運用機能。これにより、マネージ コードはインターフェイスを介してコンポーネント オブジェクト モデル (COM) オブジェクトと対話できます。
プラットフォーム呼び出しと COM 相互運用の両方で相互運用マーシャリングを使用して、呼び出し元と呼び出し先の間でメソッド引数を正確に移動し、必要に応じて戻します。 次の図に示すように、プラットフォーム呼び出しメソッド呼び出しは、 コールバック関数 が関係する場合を除き、マネージド コードからアンマネージド コードにフローします。 プラットフォーム呼び出し呼び出しはマネージド コードからアンマネージド コードへのみフローできますが、データは入力パラメーターまたは出力パラメーターとして双方向にフローできます。 COM 相互運用メソッドの呼び出しは、どちらの方向でもフローできます。
最低レベルでは、両方のメカニズムで同じ相互運用マーシャリング サービスが使用されます。ただし、特定のデータ型は、COM 相互運用機能またはプラットフォーム呼び出しによってのみサポートされます。 詳細については、「 既定のマーシャリング動作」を参照してください。
マーシャリング アンド COM アパートメンツ
相互運用マーシャラーは、共通言語ランタイム ヒープとアンマネージ ヒープの間でデータをマーシャリングします。 マーシャリングは、呼び出し元と呼び出し先が同じデータ インスタンスを操作できない場合に発生します。 相互運用マーシャラーを使用すると、呼び出し元と呼び出し先がデータの独自のコピーを持っている場合でも、同じデータで動作しているように見えます。
COM には、COM アパートメントまたは異なる COM プロセス間でデータをマーシャリングするマーシャラーもあります。 同じ COM アパートメント内のマネージド コードとアンマネージド コードの間で呼び出す場合、相互運用マーシャラーが関係する唯一のマーシャラーです。 別の COM アパートメントまたは別のプロセスでマネージド コードとアンマネージド コードの間で呼び出す場合、相互運用マーシャラーと COM マーシャラーの両方が関係します。
COM クライアントとマネージド サーバー
Regasm.exe (アセンブリ登録ツール) によって登録されたタイプ ライブラリを持つエクスポートされたマネージド サーバーには、ThreadingModel
レジストリ エントリが Both
に設定されています。 この値は、サーバーをシングル スレッド アパートメント (STA) またはマルチスレッド アパートメント (MTA) でアクティブ化できることを示します。 サーバー オブジェクトは、次の表に示すように、呼び出し元と同じアパートメントに作成されます。
COM クライアント | .NET サーバー | マーシャリングの要件 |
---|---|---|
STA |
Both は STA になります。 |
同じアパートメントでのマーシャリング。 |
MTA |
Both は MTA になります。 |
同じアパートメントでのマーシャリング。 |
クライアントとサーバーは同じアパートメント内にあるため、相互運用マーシャリング サービスはすべてのデータ マーシャリングを自動的に処理します。 次の図は、同じ COM スタイル アパートメント内のマネージドとアンマネージドのヒープ間で機能している、相互運用マーシャリング サービスを示しています。
マネージド サーバーをエクスポートする場合は、COM クライアントがサーバーのアパートメントを決定していることに注意してください。 MTA で初期化された COM クライアントによって呼び出されるマネージド サーバーは、スレッド セーフを確保する必要があります。
マネージド クライアントと COM サーバー
マネージド クライアント アパートメントの既定の設定は MTA です。ただし、.NET クライアントのアプリケーションの種類によって既定の設定が変更される場合があります。 たとえば、Visual Basic クライアント アパートメント設定は STA です。 System.STAThreadAttribute、System.MTAThreadAttribute、Thread.ApartmentState プロパティ、または Page.AspCompatMode プロパティを使用して、マネージド クライアントのアパートメント設定を調べて変更できます。
コンポーネントの作成者は、COM サーバーのスレッド アフィニティを設定します。 次の表は、.NET クライアントと COM サーバーのアパートメント設定の組み合わせを示しています。 また、組み合わせの結果のマーシャリング要件も示します。
.NET クライアント | COM サーバー | マーシャリングの要件 |
---|---|---|
MTA (既定) | MTA STA |
相互運用マーシャリング。 相互運用と COM マーシャリング。 |
STA | MTA STA |
相互運用と COM マーシャリング。 相互運用マーシャリング。 |
マネージド クライアントとアンマネージド サーバーが同じアパートメント内にある場合、相互運用マーシャリング サービスはすべてのデータ マーシャリングを処理します。 ただし、クライアントとサーバーが異なるアパートメントで初期化される場合は、COM マーシャリングも必要です。 次の図は、アパートメント間呼び出しの要素を示しています。
アパートメント間マーシャリングの場合は、次の操作を行うことができます。
アパートメント間のマーシャリングのオーバーヘッドを受け入れます。これは、境界を越える呼び出しが多くある場合にのみ認識されます。 呼び出しがアパートメントの境界を正常に越えるためには、COM コンポーネントのタイプ ライブラリを登録する必要があります。
クライアント スレッドを STA または MTA に設定して、メイン スレッドを変更します。 たとえば、C# クライアントが多数の STA COM コンポーネントを呼び出す場合、メイン スレッドを STA に設定することで、アパートメント間マーシャリングを回避できます。
注
C# クライアントのスレッドが STA に設定されると、MTA COM コンポーネントへの呼び出しには、アパートメント間マーシャリングが必要になります。
アパートメント モデルを明示的に選択する手順については、「 マネージド スレッドとアンマネージド スレッド」を参照してください。
リモートの呼び出しのマーシャリング
クロスアパートメント マーシャリングと同様に、オブジェクトが別々のプロセスに存在する場合は常に、マネージド コードとアンマネージド コード間の各呼び出しに COM マーシャリングが関係します。 例えば次が挙げられます。
- リモート ホスト上のマネージド サーバーを呼び出す COM クライアントは、分散 COM (DCOM) を使用します。
- リモート ホスト上の COM サーバーを呼び出すマネージド クライアントは、DCOM を使用します。
次の図は、相互運用マーシャリングと COM マーシャリングがプロセスとホストの境界を越えて通信チャネルを提供する方法を示しています。
ID の保持
共通言語ランタイムは、マネージド参照とアンマネージド参照の ID を保持します。 次の図は、プロセスとホストの境界を越えた直接のアンマネージド参照 (上の行) と直接マネージド参照 (下の行) のフローを示しています。
この図について:
アンマネージド クライアントは、リモート ホストからこの参照を取得するマネージド オブジェクトから COM オブジェクトへの参照を取得します。 リモート処理メカニズムは DCOM です。
マネージド クライアントは、リモート ホストからこの参照を取得する COM オブジェクトからマネージド オブジェクトへの参照を取得します。 リモート処理メカニズムは DCOM です。
注
マネージド サーバーのエクスポートされたタイプ ライブラリを登録する必要があります。
呼び出し元と呼び出し先の間のプロセス境界の数は関係ありません。インプロセス呼び出しとアウトプロセス呼び出しでは、同じ直接参照が行われます。
マネージド リモート処理
ランタイムにはマネージド リモート処理も用意されています。これを使用して、プロセスとホストの境界を越えてマネージド オブジェクト間の通信チャネルを確立できます。 次の図に示すように、マネージド リモート処理は、通信コンポーネント間のファイアウォールに対応できます。
SOAP または TcpChannel クラスを使用したファイアウォール間のリモート呼び出し
一部のアンマネージ呼び出しは、サービス コンポーネントと COM の間の呼び出しなど、SOAP を介してチャネル化できます。
関連トピック
タイトル | 説明 |
---|---|
既定のマーシャリング動作 | 相互運用マーシャリング サービスがデータのマーシャリングに使用する規則について説明します。 |
プラットフォーム呼び出しによるデータのマーシャリング | メソッド パラメーターを宣言し、アンマネージ ライブラリによってエクスポートされた関数に引数を渡す方法について説明します。 |
COM 相互運用機能を使用したデータのマーシャリング | COM ラッパーをカスタマイズしてマーシャリング動作を変更する方法について説明します。 |
方法: Managed-Code DCOM を WCF に移行する | DCOM から WCF に移行する方法について説明します。 |
方法: HRESULT と例外をマップする | カスタム例外を HRESULT にマップする方法について説明し、各 HRESULT から .NET Framework の同等の例外クラスへの完全なマッピングを提供します。 |
ジェネリック型を使用した相互運用 | COM 相互運用性のためにジェネリック型を使用する場合にサポートされるアクションについて説明します。 |
アンマネージ コードとの相互運用 | 共通言語ランタイムによって提供される相互運用性サービスについて説明します。 |
高度な COM 相互運用性 | COM コンポーネントを .NET Framework アプリケーションに組み込む方法の詳細へのリンクを提供します。 |
相互運用に関する設計上の考慮事項 | 統合 COM コンポーネントを記述するためのヒントを提供します。 |
リファレンス
.NET