2013-02-11 95 views
6

我在VC++中有一個第三方COM組件,它的C++接口。我在下面的調用中崩潰了,這正在導致我的應用程序崩潰。我怎樣才能從這個功能恢復優雅,這不是我的應用程序的一部分?如何正常恢復COM錯誤?

inline _RecordsetPtr IGLibMgr::GetLibInfo (_bstr_t LibPath) { 
    struct _Recordset * _result = 0; 
    HRESULT _hr = raw_GetLibInfo(LibPath, &_result); 
    if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); 
    return _RecordsetPtr(_result, false); 
} 

它在最後一行崩潰。我不認爲我可以修改這些代碼,因爲它是第三方COM的東西。我真的有什麼選擇?我只想給用戶提供消息框並優雅地返回。

+1

您確定*它不是「崩潰」,因爲您沒有捕獲由於「FAILED(_hr)」狀態而拋出的_com_error&如果你調試了這個,我會*幾乎*保證正在生成的hresult有SEVERITY位點亮(導致'FAILED()'評估爲非零的東西) – WhozCraig 2013-02-11 16:21:43

+0

我只是不熟悉COM,是否需要捕獲它與catch()塊? – zar 2013-02-11 16:28:46

+0

是的。一般的規則是,如果可以拋出異常,或者需要捕捉並處理它,或者***知道你的調用者會這樣做。這聽起來好像都沒有完成。 MSVC的'comutil'支持層非常強大;幾乎是一種方法論。我已經包含了一個如何處理下面的示例。 – WhozCraig 2013-02-11 16:31:34

回答

5

如果你不是已經這樣做在你的代碼,你需要從呼叫側:

try 
{ // setup your invoke for your object... 
    IGLibMgrPtr spMgr = .... 
    bstr_t bstrPath = .... 

    // invoke your call. 
    _RecordsetPtr spRS = spMgr->GetLibInfo(bstrPath); 

    ... continue normal processing ... 
} 
catch(const _com_error& ce) 
{ 
    // handle your error here. 
} 

這是多層次的重要。最顯而易見的是,你的IGLibMgr成員不僅可以拋出異常,bstr_t分配等等也可以。當使用來自COM DLL的代碼#import時,如果使用MSVC的comutil庫生成的智能指針,則可以習慣這種格式。

注:_com_error類提供了幾個成員獲得爲什麼發生錯誤,包括HRESULT,錯誤描述字符串,等等。它甚至還提供了訪問由錯誤返回對象創建的IErrorInfo如果是那麼好的爲提供這種詳細程度。

+0

更好地捕捉到const:'catch(const _com_error&ex){...}' – nogard 2013-02-11 16:32:01

+0

@nogard egads我至少在一個項目中有一百萬行代碼,我需要這樣做,現在你提到了它。 = P – WhozCraig 2013-02-11 16:32:55