2015-12-17 10 views
5

IXMLDocument(msxmlラッパー)を使用しているときに、DLL機能内でCoInitializeを使用する理由はありますか? (またはその他のcomオブジェクト)DLL内でIXMLDocumentを使用するにはCoInitializeが必要ですか?

呼び出し側のアプリケーション/スレッドは、CoInitialize/CoUninitializeを呼び出していますか?

ComObjをDLLの内部で使用すると、その初期化セクションでCoInitializeが自動的に呼び出され、ファイナライズセクションでCoUninitializeが自動的に呼び出されます。

答えて

8

呼び出しアプリケーション/スレッドは、CoInitialize/CoUninitializeを呼び出しますか?

はい。原則として、スレッドの作成者はCOMの初期化を担当する必要があります。つまり、DLLから公開する関数は、呼び出されたスレッドのCOMを初期化してはなりません。

DLLを呼び出すスレッドでCOMを初期化する責任を負うと、そのスレッドの作成者に不合理な制約が課されるためです。スレッドの作成者がCOMを初期化する必要がある別のアクションを実行する必要がある場合はどうなりますか?標準的な方法は、DLLがCOM初期化をその要件の1つとして指定することです。 DLLのドキュメントで、呼び出し元がCOMを初期化する必要があることを示します。

詳細:Things you shouldn't do, part 2: Dlls can't ever call CoInitialize* on the application’s thread

そのため、呼び出し元のスレッドでDLL内のCOMを初期化しないでください。初期化セクションでCOMを初期化しない理由はさらにあります。初期化セクションは、DLLのDllMainの内部で実行されます。 DllMainの中で呼び出すことができるものはほとんどありません.COMの機能は許可されたアクションのリストにありません。詳細はSome reasons not to do anything scary in your DllMain, part 3です。

自分のDLL内で、初期化セクションでCoInitializeを自動的に呼び出し、ファイナライズセクションでCoUninitializeするComObjを使用するとどうなりますか?

ComObj単位ではありません。 DLLの場合、参照するCOM初期化コードは表示されません。 ComObjを含めると、COMは実行可能プロジェクトでは初期化されますが、ライブラリでは初期化されません。

+0

しかし、DLLまたはDLL自体が使用するユニットの1つが間接的に "ComObj"ユニットを使用するとどうなりますか?もし私がそれにどのように取り組まなければならないのですか? – zig

+1

より一般的なルールは次のとおりです。COMは、スレッドの作成者/所有者によってのみ初期化される必要があります。 DLLがCOM操作を実行するために独自のスレッドを作成する場合、DLLはそれらのスレッドのCOMを初期化します。 – IInspectable

+0

@zigまあ、もしあれば?まったく問題はありません。呼び出し元は指示どおりにCOMを初期化します。そしてあなたのDLLは 'ComObj'の関数を使っても問題ありません。 DLLに 'ComObj'を使っても、COMは初期化されません。それはGUIアプリケーションでのみ発生します。 –

関連する問題