Out-OF-Proc COM サーバーへの非同期呼び出しをカプセル化する関数を DLL に実装しました。次のようになります。
HRESULT hr = S_OK;
bool bCoInitialized = false;
IXXXXInterface* pServer = NULL;
ISynchronize* pISynchronize = NULL;
AsyncIXXXXInterface* pAsyncServer = NULL;
ICancelMethodCalls* pICancel = NULL;
hr = CoInitializeEx(NULL,COINIT_MULTITHREADED);
if (hr == S_OK || hr == S_FALSE) {
bCoInitialized = true;
}
else if(hr == RPC_E_CHANGED_MODE) {
bCoInitialized = false;
}
else{
bCoInitialized = false;
goto cleanup
}
hr = CoCreateInstance(CLSID_XXXXInterface, NULL,
CLSCTX_ALL|CLSCTX_ACTIVATE_64_BIT_SERVER, IID_IXXXXInterface, (void**)&pServer);
if (FAILED (hr)) {
goto cleanup
}
ICallFactory* pCallFactory;
hr = pServer->QueryInterface (IID_ICallFactory, (void**) &pCallFactory);
if (FAILED (hr)) {
goto cleanup
}
hr = pCallFactory->CreateCall (IID_AsyncIXXXXInterface, NULL, IID_AsyncIXXXXInterface,
(IUnknown**) &pAsyncServer);
pCallFactory->Release();
if (FAILED (hr)) {
goto cleanup
}
hr = pAsyncServer->QueryInterface(IID_ISynchronize, (void**) &pISynchronize);
if (FAILED (hr)) {
goto cleanup
}
hr = pAsyncServer->QueryInterface(IID_ICancelMethodCalls, (void**) &pICancel);
if (FAILED (hr)) {
goto cleanup
}
// Do something use the async interface.
cleanup:
if(pICancel)
pICancel->Release();
if(pISynchronize)
pISynchronize->Release();
if(pAsyncServer)
pAsyncServer->Release();
if(pServer)
pServer->Release();
if(bCoInitialized) // If I comment out these
CoUninitialize(); // 2 lines, it will be OK.
問題は、マルチスレッドで関数を呼び出すと、COM のワーク スレッドのコール スタックで compase.dll で例外がスローされることがあります。最後の2行だけコメントアウトすればOKです。COM スレッド プール内のワーク スレッドがまだリソースを使用している間に、CoUnitialize() がすべてのリソースを解放するようです。私の考えが正しいのか、どこかに問題があるのか わかりません。私が正しければ、作業スレッドがすべてのリソースを解放するのを待つ API を使用して、この問題を回避するにはどうすればよいですか?