【发布时间】:2020-01-08 05:11:24
【问题描述】:
以下函数是在 Microsoft Visual Studio 2017 中编译的。在该函数中,CAttributedObject 是实现IObjectID 接口的 COM 类。该函数必须处理有关事件的通知。参数pCaller 是指向CAttributedObject 类型对象的指针,它是事件的来源。通知通过其消息队列分派到主线程。预计在通知到达的那一刻,pCaller指向的对象可以被销毁;这就是代码中出现 try/catch 块的原因。
然而,有时,对QueryInterface 的调用会引发“纯虚拟调用”异常,该异常未被捕获并导致应用程序崩溃。在许多其他情况下,我们使用 try/catch 测试对可能已删除的内存的访问,并且所有这些都已经工作了多年。我不明白为什么“纯虚拟调用”异常很特别。
HRESULT CDataProvider::OnObjIconChanged(
BSTR Key, BSTR Path, IUnknown* pCaller,
UINT Flags, __int64 hIcon, const CLSID& ProviderCLSID)
{
CAttributedObject* pAttrObj = 0;
IObjectID* pObjID = 0;
try {
try { pCaller->QueryInterface(__uuidof(IObjectID), (void**)&pObjID); }
catch(...) {}
if (pObjID != 0)
pAttrObj = static_cast<CAttributedObject*>(pObjID);
if (pAttrObj != 0)
{
pAttrObj->SetIcon((HICON)hIcon, Flags & SHGFI_SMALLICON);
pAttrObj->Release();
}
} catch(...) {}
TreeService()->Fire_ObjIconChanged(Key, Path, hIcon);
return S_OK;
}
【问题讨论】:
-
评论不用于扩展讨论;这个对话是moved to chat。
-
" pCaller 指向的对象可以被销毁" 也许你在某处缺少
AddRef/Release对。 -
第一个错误是称其为“纯虚拟调用异常”。 “纯虚拟通话”也不例外。