本記事は、COM Advent Calendar 2014 – Qiitaの10日目の記事です。10日でした。


今後、COM Advent Calendarでアパートメント間のマーシャリングの話をしたいので、今日は駆け足でアパートメントの説明をします。

アパートメントの概要

COMでは、プロセス内のスレッド1個以上からなるアパートメントがオブジェクト管理の1つの単位となっています。すべてのオブジェクトはいずれかのアパートメントに所属します。そして、メソッド呼び出しはオブジェクトの所属するアパートメント内のスレッドに転送された上で実行されます。そのため、たとえば、以下のようなことが透過的に実現されています。

  • UI関係のオブジェクトは必ずUIスレッドで実行する。
  • ディスク・ネットワークなどのIOはその他の適当なスレッドで実行する。

マーシャリング

上記を実現するため、アパートメントをまたいでのインタフェースへのポインタを直接やりとりは原則としてできません。アパートメントをまたぐオブジェクトのやりとりはマーシャリングと呼ばれる処理を介する必要があります。マーシャリングはメソッド呼び出しで暗黙に実施されることもあれば、APIで明示的・暗黙的に行うこともあります。

プロセス内に限らず、別プロセスのアパートメント間でもマーシャリングは可能です。このため、プロセス間通信にも使えます。さらに別コンピュータ同士でも可能で、これがいわゆるDCOMです。

なお、COM Advent Calendarでは、同一コンピュータ内のプロセス間通信までを扱う予定です。

スレッドとアパートメント

2日目(スレッド初期化・終了関数のまとめ)で紹介したCOMの初期化関数は、いずれもスレッドをどの種類のアパートメントに入れるか指定する機能を持ちます。

アパートメントには、以下の種類があります。通常、MTAとSTAから選びます。

STA (Single-threaded apartment), ASTA (Application Single-Threaded Apartment)
STAは1スレッドだけ所属できるアパートメントです。STAは新しいスレッドがCoInitializeEx(COINIT_APARTMENTTHREADED)やOleInitialize()するたびに作られます。ASTAはストアアプリ (WinRT API)用のSTAの変種です。
MTA (Multithreaded Apartment)
MTAは複数スレッドが所属できるアパートメントです。その代わり、プロセスに1つだけで共有です。CoInitializeEx(COINIT_MULTITHREADED)やRoInitialize(RO_INIT_MULTITHREADED)は、「プロセスにMTAがあればそこに加わり、なければ作る」という処理を行います

STA/ASTAとMTAの違いは回を改めて取り上げる予定です。

まとめ

COMでは、アパートメントというスレッドの集合の上でオブジェクトを管理しています。アパートメント間でのオブジェクトのやりとりにはマーシャリングと呼ばれる調停処理が必要です。また、アパートメントには、STA/ASTAとMTAの大きく2種類あり、スレッドごとに選択できます。


なんと、プロキシ・スタブやRPCという言葉は今回登場しませんでした。次回以降に説明するかもしれません。

また、今日の話では様々な事柄を省略しています。アパートメント内で細分する単位としてコンテキストがあることや、Neatral Apartmentなどがあります。これらはだいたい、私が使ったことないから説明しようがないからで、今後COM Advent Calendarでも登場の見込みは薄いです。

今からこの辺のことをきちんと学ぶには何を参照したら良いのでしょうかね。私も知りたいです。


スポンサード リンク

この記事のカテゴリ

  • ⇒ COMにおけるアパートメントの概要