C 我应该什么时候打电话给你?
我在DLL中实现了一个函数,它封装了对进程外COM服务器的异步调用。看起来是这样的:C 我应该什么时候打电话给你?,c,com,mta,C,Com,Mta,我在DLL中实现了一个函数,它封装了对进程外COM服务器的异步调用。看起来是这样的: HRESULT hr = S_OK; bool bCoInitialized = false; IXXXXInterface* pServer = NULL; ISynchronize* pISynchronize = NULL; AsyncIXXXXInterface* pAsyncServer = NULL; ICancelMethodCalls* pICan
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的工作线程中的combase.dll中抛出异常,并带有调用堆栈。
如果我只注释掉最后两行,就可以了。在某些情况下,当COM线程池中的工作线程仍在使用资源时,conInitialize()似乎将释放所有资源。我不确定我的想法是否正确,或者其他地方出了问题。如果我是对的,如何通过使用哪个API等待工作线程释放所有资源来避免这个问题?您需要将CoInitializeEx()的失败视为致命问题,它应该终止您的程序。当您更改RPC_E__模式时,出现了严重错误,这是代码中的一个错误,如果什么都没有发生,那么继续下去将不会有好结果。您尚未指定崩溃是在此进程中的RPC线程中还是进程外COM服务器进程中。无论哪种方式,听起来都好像您没有正确地封送到另一个单元,很可能是在您设置的回调接口上,该接口从未正确撤消。因为这是程序外的,所以你的公寓模型没有真正的区别。在另一个过程中,你必须正确地移动到公寓。除此之外,如果您在
CoInitializeEx()
上失败(hr),那么采取任何COM操作都是错误的。