ごめん、忘れてた。
投稿カレンダーはJavaScriptが有効でない環境では使用できません。
aetos
埼玉を馬鹿にする奴は俺が許さん。
基本的に知ったかぶり。興味を持った技術に手を出して、ちょっと齧りはするものの、それを応用して何か形にするまでは及ばずに飽きて放り出す人。
Microsoft MVP for Windows SDKJuly 2007 - February 2008Microsoft MVP for Visual C++February 2008 - June 2009
グリムス(gremz)はJavaScriptが有効でない環境では使用できません。
e-WordsはJavaScriptが有効でない環境では使用できません。
Amazon 広告はJavaScriptが有効でない環境では使用できません。
MTAとかは当たり前にスレッドセーフなので置いといて。
DllGetClassObjectとDllCanUnloadNowとか、クラスファクトリもスレッドセーフにしなきゃならないですよね?
投稿日時 : 2007年12月21日 14:35
クラスファクトリは、STAクラスのファクトリなら考えなくていいかもしれない。
プロセス内にSTAスレッドは複数存在できるので、基本的にインプロセスサーバDLLのすべてのエクスポート関数とクラスファクトリはスレッドセーフでなければなりません。 と Effective COM かどこかに書いてた気がします。
うぃ。 で、DllCanUnloadNowがスレッドセーフでなければならないということは、モジュールロックカウンタは排他制御しなければならんというわけで。 STDAPI DllCanUnloadNow() { if( moduleCount == 0 ) { //※ return S_OK; } return S_FALSE; } ※のタイミングで新しいインスタンスが作られることは阻止しなければならないと思うんですが、そこまで書いてるサンプルコードはまず見ない。 あと、クラスファクトリオブジェクトが属するアパートメントは何なんだろう? と思うわけなんですが、試してみた結果、DllGetClassObject や IClassFactory::CreateInstance は、その引数に渡される CLSID を持つクラスのスレッドコンテキストで呼ばれるみたいだと。 DllGetClassObject が、呼ばれる都度、新しいクラスファクトリオブジェクトを作って返す場合、かつ、そのクラスファクトリオブジェクトが STA オブジェクトしか作らない場合、クラスファクトリのメソッドが呼ばれるスレッドは固定? これは試してみないといかんな。 ちなみに、DllGetClassObject が、呼ばれる都度、新しいクラスファクトリオブジェクトを作る場合、クラスファクトリはスレッドセーフを考慮しなくてよい、と解説されてるものも目にしますが、嘘ですね。 あと、DLL のエクスポート関数は常にプロセスのプライマリSTAで実行されるという記述も見かけますが、嘘ですね。
> DllGetClassObject が、呼ばれる都度、新しいクラスファクトリオブジェクトを作って返す場合、かつ、そのクラスファクトリオブジェクトが STA オブジェクトしか作らない場合、クラスファクトリのメソッドが呼ばれるスレッドは固定? これは試してみないといかんな。 固定がどこを指してるのかは分かりませんが、呼び出し元のアパートメントに依存するのではないでしょーか。 > あと、DLL のエクスポート関数は常にプロセスのプライマリSTAで実行されるという記述も見かけますが、嘘ですね。 コンポーネントのThreadingModelが設定されていない場合、CoFreeUnusedLibraries(Ex)を直接呼び出さなければ、この動作で正しいはずです。 CoFreeUnusedLibraries(Ex)を直接呼び出した場合、DllCanUnloadNowは呼び出したスレッドのコンテキストで実行されます。 この場合でも、プライマリSTAスレッド以外のCoUninitialize呼び出しによるDllCanUnloadNowの呼び出しは発生しないではないかと思っています。 (この動作は未検証)
Powered by: Copyright © αετος