相互運用マーシャリングの概要

多くのデータ型の表現はマネージ メモリ内でもアンマネージ メモリ内でも共通しています。これらのデータ型の処理は相互運用マーシャラによって自動的に行われます。その他の型は、マネージ メモリ内ではあいまいになるか、まったく表現されないこともあります。

あいまいな型には、単一のマネージ型に割り当てられる複数のアンマネージ表現があるか、または配列のサイズなどの型情報が不足しています。あいまいな型については、マーシャラは既定の表現と代替表現を提供するため、複数の表現が存在することになります。このため、あいまいな型をどのようにマーシャリングするかについて、マーシャラに対して明確に指示できるようになっています。

ここでは、プラットフォーム呼び出しと COM 相互運用機能を使用したプログラミング モデルを確認することから始めます。相互運用マーシャリングと COM マーシャリングがどのように統合されるかについては、サブトピック「マーシャリングと COM アパートメント」で説明します。次に、マーシャラが分散環境でどのように動作するかについては、サブトピック「リモート呼び出しのマーシャリング」で説明します。

プラットフォーム呼び出しモデルと COM 相互運用機能モデル

共通言語ランタイムには、アンマネージ コードとの相互運用性をサポートするために、次の 2 つの機構が用意されています。

  • プラットフォーム呼び出しを使用すると、マネージ コードはアンマネージ ライブラリからエクスポートされた関数を呼び出すことができます。

  • COM 相互運用機能を使用すると、マネージ コードはインターフェイスを通じて COM オブジェクトと対話できます。

プラットフォーム呼び出しと COM 相互運用機能は、どちらも相互運用マーシャリングを使用することで、メソッドの呼び出し元から呼び出し先に引数を正確に渡し、必要に応じて呼び出し元に引数を返します。次の図に示すように、コールバック関数が関連する場合を除くと、プラットフォーム呼び出しはマネージからアンマネージへという方向で流れ、逆方向に流れることはありません。プラットフォーム呼び出しはマネージ コードからアンマネージ コードへとしか流れませんが、データは In パラメータまたは Out パラメータとして両方向に流れることができます。COM 相互運用機能のメソッド呼び出しは両方向に流れます。

プラットフォーム呼び出しと COM 相互運用呼び出しの流れ

プラットフォーム呼び出し

最低水準では、両方の機構が同じ相互運用マーシャリング サービスを使用します。ただし、一部のデータ型は、COM 相互運用機能またはプラットフォーム呼び出しのいずれか一方だけによってサポートされます。詳細については「既定のマーシャリングの動作」を参照してください。

マーシャリングと COM アパートメント

相互運用マーシャラは、共通言語ランタイム ヒープとアンマネージ ヒープ間でデータをマーシャリングします。マーシャリングは、呼び出し元と呼び出し先が同じデータ インスタンスに対して操作を実行できない場合に必ず実行されます。相互運用マーシャラを使用した場合は、呼び出し元と呼び出し先が同じデータを操作しているように見えますが、実際にはそれぞれがデータのコピーを使用しています。

COM にもマーシャラがあり、このマーシャラは COM アパートメント間、または別の COM プロセス間でデータのマーシャリングを行います。同じ COM アパートメントに属するマネージ コードとアンマネージ コードの間で呼び出しを行う場合に関連するマーシャラは、相互運用マーシャラだけです。異なる COM アパートメントまたは異なるプロセスに属するマネージ コードとアンマネージ コードの間で呼び出しを行うときは、相互運用マーシャラと COM マーシャラの両方が関連します。

COM クライアントと Windows Server 2003

アセンブリ登録ツール (Regasm.exe) によって登録されたタイプ ライブラリを含む、エクスポートされたマネージ サーバーの場合、ThreadingModel レジストリ エントリは Both と設定されます。この値は、シングルスレッド アパートメント (STA: Single-Threaded Apartment) またはマルチスレッド アパートメント (MTA: MultiThreaded Apartment) でサーバーをアクティブにできることを示します。サーバー オブジェクトは、次の表に示すように、その呼び出し元と同じアパートメント内に作成されます。

COM クライアント Windows Server 2003 必要なマーシャリング

STA

Both が STA になります。

同一アパートメント内のマーシャリング

MTA

Both が MTA になります。

同一アパートメント内のマーシャリング

クライアントとサーバーが同じアパートメント内にあるため、相互運用マーシャリング サービスはすべてのデータ マーシャリングを自動で処理します。COM スタイルの同じアパートメント内のマネージ ヒープとアンマネージ ヒープ間で機能する相互運用マーシャリング サービスを次の図に示します。

同一アパートメント内のマーシャリング プロセス

相互運用マーシャリング

マネージ サーバーをエクスポートする予定がある場合は、COM クライアントによってサーバーのアパートメントが決定されることに注意してください。MTA 内で初期化された COM クライアントによって呼び出されるマネージ サーバーは、確実にスレッド セーフにする必要があります。

.NET クライアントと COM サーバー

.NET クライアント アパートメントに関する既定の設定は MTA です。ただし、.NET クライアントのアプリケーションの種類によって既定の設定が変わることがあります。たとえば、Visual Basic 2005 クライアント アパートメントの設定は STA です。マネージ クライアントのアパートメントの設定を調べて変更するには、STAThreadAttributeMTAThreadAttributeThread.ApartmentState、または Page.AspCompatMode の各プロパティを使用できます。

コンポーネントの作成者が COM サーバーのスレッド アフィニティを設定します。.NET クライアントと COM サーバーに対するアパートメント設定の組み合わせを次の表に示します。また、それらの組み合わせで必要となるマーシャリングも示します。

.NET クライアント COM サーバー 必要なマーシャリング

MTA (既定)

MTA

STA

相互運用マーシャリング

相互運用マーシャリングと COM マーシャリング

STA

MTA

STA

相互運用マーシャリングと COM マーシャリング

相互運用マーシャリング

マネージ クライアントとアンマネージ サーバーが同じアパートメント内にある場合、相互運用マーシャリング サービスがすべてのデータ マーシャリングを処理します。ただし、クライアントとサーバーが異なるアパートメント内で初期化される場合は、COM マーシャリングも必要です。アパートメント間呼び出しの要素を次の図に示します。

.NET クライアントと COM オブジェクト間のアパートメント間呼び出し

COM マーシャリング

アパートメント間マーシャリングについては、次の処理を実行できます。

  • アパートメント間マーシャリングによるオーバーヘッドを受け入れます。このオーバーヘッドは、アパートメント境界を越えた呼び出しが何回も行われる場合にだけ認識されます。アパートメントの境界を越えた呼び出しを正常に行うためには、COM コンポーネントのタイプ ライブラリを登録する必要があります。

  • クライアント スレッドの設定に応じてメイン スレッドを STA または MTA に変更します。たとえば、C# クライアントが多数の STA COM コンポーネントを呼び出す場合は、メイン スレッドを STA と設定することでアパートメント間マーシャリングを回避できます。

    Noteメモ :

    C# クライアントのスレッドを STA と設定した後で MTA COM コンポーネント呼び出すためには、アパートメント間マーシャリングが必要になります。

明示的にアパートメント モデルを選択するための手順については、「マネージ スレッドとアンマネージ スレッド」を参照してください。

リモート呼び出しのマーシャリング

アパートメント間マーシャリングの場合と同様に、オブジェクトが別個のプロセス内に存在するときには、マネージ コードとアンマネージ コード間で呼び出しが行われるたびに、COM マーシャリングが必要になります。たとえば、次のようにします。

  • リモート ホスト上でマネージ サーバーを呼び出す COM クライアントが DCOM を使用する場合

  • リモート ホスト上で COM サーバーを呼び出すマネージ クライアントが DCOM を使用する場合

相互運用マーシャリングと COM マーシャリングが、プロセスやホストの境界を越えて通信チャネルを確立するしくみを次の図に示します。

プロセス間マーシャリング

COM マーシャリング

ID の維持

共通言語ランタイムはマネージ参照とアンマネージ参照の ID を維持します。プロセスとホストの境界を越えた直接アンマネージ参照 (上の行) と直接マネージ参照 (下の行) の流れを次の図に示します。

プロセスとホストの境界を越えた参照渡し

COM 呼び出し可能ラッパーとランタイム呼び出し可能ラッパー

この図では次のことがわかります。

  • アンマネージ クライアントは、COM オブジェクトへの参照をマネージ オブジェクトから取得し、マネージ オブジェクトはこの参照をリモート ホストから取得します。リモート処理機構は DCOM です。

  • マネージ クライアントは、マネージ オブジェクトへの参照を COM オブジェクトから取得し、COM オブジェクトはこの参照をリモート ホストから取得します。リモート処理機構は DCOM です。

    Noteメモ :

    マネージ サーバーのエクスポートされたタイプ ライブラリを登録する必要があります。

呼び出し元と呼び出し先の間にプロセス境界がいくつあるかは関係ありません。つまり、プロセス内呼び出しとプロセス外呼び出しについて同じ直接参照が行われます。

マネージ リモート処理

ランタイムはマネージ リモート処理も提供します。これを使用すると、マネージ オブジェクト間でプロセスやホストの境界を越えて通信チャネルを確立できます。マネージ リモート処理では、次の図に示すように、通信コンポーネント間にファイアウォールがある場合にも対処できます。

SOAP または TcpChannel クラスを使用した、ファイアウォールを越えたリモート呼び出し

SOAP または TcpChannel

サービスを受けるコンポーネントと COM の間の呼び出しのように、SOAP を通じてチャネリングできるアンマネージ呼び出しもあります。マネージ リモート処理の使用方法に関する追加情報については、「.NET リモート処理の概要」を参照してください。

参照

その他の技術情報

相互運用マーシャリング
既定のマーシャリングの動作
プラットフォーム呼び出しによるデータのマーシャリング
COM 相互運用機能によるデータのマーシャリング