ソモサン

私rohkiによる活動や読書の記録をつらつらと書くページです

ややこしい COM とスレッドの初期化(?)をコードにする

Windows に相も変わらずどっぷりの rohki です。

Windows には COM という便利な、便利な仕組みがあります。

この COM とスレッドが絡むと、アパートメントという仕組みが出てきます。
COM ライブラリを初期化する (Windows)
上記を参照すると、以下のように使い分けるとよい、とのこと。

  • スレッドでウィンドウを作成するなら、アパートメント スレッド(COINIT_APARTMENTTHREADED)
  • 持たないなら、マルチスレッド(COINIT_MULTITHREADED)

まぁ、だいたいはマルチスレッドでしょう。*1
この切り替えは、スレッドに対して CoInitializeEx で設定します。*2

で、これ設定したら CoUninitialize で解除しなきゃなんですが、いちいち気にしたくないです。
なんで、以下のようなクラスを作ってみるとよいかなーって考えてます。

COMUtils

TThread.Execute は final でこのクラス以降で override 出来ないようにして、実質的な処理をかく関数を別に用意する形です。
こうすると利用する人はいちいち気にしなくても良いことになります。

CreateCoInitializeEx を書けば、って僕も一番最初思ったんですが、この設定は先ほどもあげたようにスレッドに対してする必要があるんです。
Create 処理を行うのは当然呼び出し元スレッドなので、生成されたスレッドに設定が適用されないままとなります。
だからわざわざこんなことしてます。

あー、ややこし。

*1:Delphi でフォームを持つと暗黙的に COINIT_APARTMENTTHREADED と聞いた気がしないでもないです

*2:設定なのに Initialize…