私は疑問を持っています。COM を初期化し、CoCreateInstance を実行して、いくつかのインターフェイスを使用します。Release を呼び出さずに CoUninitialize を呼び出すことはできますか? メモリ/リソースリークが発生しますか?
前もって感謝します、-マニ。
私は疑問を持っています。COM を初期化し、CoCreateInstance を実行して、いくつかのインターフェイスを使用します。Release を呼び出さずに CoUninitialize を呼び出すことはできますか? メモリ/リソースリークが発生しますか?
前もって感謝します、-マニ。
MSDN から:
http://msdn.microsoft.com/en-us/library/ms688715%28VS.85%29.aspx
CoUninitialize はアプリケーションのシャットダウン時に呼び出す必要があります。これは、アプリケーションがメイン ウィンドウを非表示にしてメイン メッセージ ループを通過した後に COM ライブラリに対して行われる最後の呼び出しだからです。開いている会話が残っている場合、CoUninitialize はモーダル メッセージ ループを開始し、この COM アプリケーションのコンテナーまたはサーバーから保留中のメッセージをディスパッチします。メッセージをディスパッチすることにより、CoUninitialize は、保留中のメッセージをすべて受信する前にアプリケーションが終了しないようにします。非 COM メッセージは破棄されます。
シャットダウン時にのみ CoUninitialize を呼び出す必要があり、それまではメモリ リークがあっても問題ありません。
COM を非初期化するかどうかに関係なく、Release の呼び出しを省略すると、サーバー側でオブジェクトが生きたままになり、理由もなくサーバー全体が稼働し続ける可能性があります (サービスとして実行されていない場合)。つまり、サーバー側でメモリ リークが発生します。これは、COM サーバーを再起動することによってのみ解消できます。
初めて COM を使い始めたときに、同様の質問をしたことを覚えています。私が取り組んでいたクライアントは多くのスレッドを使用しており、各スレッドで実行されるさまざまなタスクにインターフェイスを再利用しようとしていました。これにより、インターフェイス キャッシュの管理が非常に困難になりました。結局、ショートカットはありませんでした。MTA、GIT、またはインターフェイス マーシャリングを使用していない限り、インターフェイスを作成したスレッドもそれを解放する必要があります。
簡単にするために、CComPtrを使用して、作成したインターフェイスを管理してみてください。通常のポインターと同様に、スマート ポインターを使用すると、作業がずっと楽になることがあります。
オブジェクトを呼び出す代わりにCoUninitialize() を使用しないIUnknown::Release()
でください。これらはまったく異なる関数です。
IUnknown::Release()
オブジェクトの参照カウントを減らすだけで、破壊される可能性があります。マーシャリングが使用されていない場合、この呼び出しは vtable を介して直接行われ (制御は COM サーバー コードに直接渡されます)、COM サブシステムはそのために何もしません。
CoUninitialize() は、マーシャリング関連のオブジェクトであると思われる呼び出しスレッドの COM 関連のリソースを解放します。マーシャリングが使用されていない場合、コードだけがそれらについて知っているため、オブジェクトは解放されないままになります。
そのため、別の代わりに使用しないでください。
私の知る限り、CoUninitializeは、現在のスレッドで使用されているすべてのCOMリソースを解放することが「想定」されています。私はそれに頼るつもりはありません。uninitialize を呼び出す前に、すべてを解放するようにします。