COM開發拾粹<二> (轉)
COM開發拾粹
5.自定義錯誤程式碼?HRESULT?異常?
COM中的出錯處理可以有多種選擇,比如用方法的[out,retval]引數返回自定義的錯誤程式碼;或返回標準的以及自定義的HRESULT值;丟擲異常也是一種選擇。採用哪種方法要根據實際情況而定。
返回自定義錯誤程式碼是一種源自C語言結構化設計的傳統方法,它放棄了C++以及COM的出錯處理機制,採用自建的處理方法。程式碼上少不了要寫很多的switch-case語句以捕捉錯誤程式碼進行處理。它的缺點是最外層程式碼要想得到最內層的錯誤的話,則中間層就必須如實的返回內層的出錯程式碼,這樣一層層的”抄送”給最外層。帶來的負作用就是靈活性非常差。
異常(exception)可以解決這個問題。但在COM規範裡規定,一個COM不能讓任何異常逃脫到這個COM之外,原因是你不知道這個COM的客戶端語言是否支援異常機制,它能不能捕獲(catch)到這個異常。規定是死的,人的活的。如果客戶端缺定也是C++編寫的,並且你也不需要編寫那麼”規範”的COM,而只要實用就行,那麼從COM裡丟擲異常,客戶端來捕獲又何妨?不過,這種”玩法”最好僅在程式內DLL中使用,跨程式、跨機器的異常能不能被正常捕獲,COM規範裡可沒承諾什麼,本來你就沒用COM的推薦方法嘛。
那什麼是COM的推薦方法,答案是HRESULT。我們可以返回一個HRESULT值表示某種錯誤。很多情況下,我們都懶得去查預定義的HRESULT值,更不願意自已定義HRESULT了,於是幾乎所有的方法都是返回S_OK或E_FAIL。其實32位長的HRESULT給我們留出了充足的空間來定義自已的錯誤碼。你可以把HRESULT值定義在IDL中,這樣當客戶端#import這個COM時,也會把定義自動加到*.tlh檔案中,無需附加的.h檔案宣告:
cpp_quote("//自定義錯誤碼"):namespace prefix = o ns = "urn:schemas--com::office" />
cpp_quote("#define E_IDNOTFOUND 0x8000F001")
cpp_quote("#define E_XIST 0x8000F002")
cpp_quote("#define E_IDREQUIRED 0x8000F003")
客戶端處理HRESULT值分為兩種情況。如果你用VC寫客戶端,用#import預編譯指令生成了COM的智慧封裝,那麼這個封裝會自動把錯誤的返回碼轉成一個異常丟擲。如下面是#import生成的封裝程式碼:
inline _variant_t IContext::GetContextValue ( _bstr_t PropName ) {
VARIANT _result;
VariantInit(&_result);
HRESULT _hr = get_ContextValue(PropName, &_result); //呼叫真正的方法
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); //如果返回一個ERROR值,_com_issue_errorex就丟擲異常
return _variant_t(_result, false);
}
這樣的封裝程式碼讓我們即可以享受到特定語言(C++)提供的便利,又可以在開發COM時遵守統一的規範而不需根據客戶端作特殊的處理。來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993477/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- COM開發拾粹<一> (轉)
- JS 專案拾粹 六: 將 Markdown 轉為思維導圖的開源工具JS開源工具
- JS 專案拾粹 二:自動生成中國山水畫的 JS 實現JS
- 使用純粹的JS構建 Web ComponentJSWeb
- 《書評《自適應軟體開發》(二)--.com時代的遺物 (轉)
- JS 專案拾粹 三: 唯一 ID 頭像圖片生成的 JS 庫JS
- 使用C#開發COM+元件 (轉)C#元件
- 玩轉iOS開發:iOS中的GCD開發(二)iOSGC
- JS 專案拾粹 四: TimeCat 超高壓縮比的網頁無損錄屏JS網頁
- (零) React Native 專案開發拾遺React Native
- 二分查詢(一)——純粹的二分查詢
- 玩轉iOS開發:iOS中的NSOperation開發(二)iOS
- AS拾遺--向PM學習二
- webpack 拾翠:充分利用 CommonsChunkPlugin()WebPlugin
- 玩轉 React(二)- 新型前端開發方式React前端
- JS 專案拾粹 五: 一行 JS 程式碼讓網頁從亮模式變為暗模式JS網頁模式
- 【轉】交換機開發(二)—— 三層交換機報文轉發過程
- 基於gin的golang web開發:Gin技術拾遺GolangWeb
- 簡單純粹
- 企業應用開發架構談(二) (轉)架構
- 玩轉iOS開發:iOS開發中的裝逼技術 – RunTime(二)iOS
- 玩轉iOS開發:iOS開發中的裝逼技術 - RunTime(二)iOS
- 玩轉iOS開發:實戰開發中的GCD Tips小技巧 (二)iOSGC
- MaxCompute Mars開發指南
- DCOM實現分散式應用(二) (轉)分散式
- 中文RFC文件遠端COM選項(二) (轉)
- 研發流程(二)(轉)
- .NET 基礎拾遺(5):多執行緒開發基礎執行緒
- PHP 轉 Node 筆記(二. 基礎的Web開發)PHP筆記Web
- 職教系統專案開發手冊(二) (轉)
- MIS系統開發中的專案管理(二)(轉)專案管理
- 軟體開發質量管理層次模型(二)(轉)模型
- 《Inside ATL/COM》第二期電子雜誌隆重發布 (轉)IDE
- 開發 Laravel 的 Composer 包Laravel
- Composer & Laravel 包本地開發Laravel
- cloud compare二次外掛化功能開發詳細步驟(一)Cloud
- 模組化開發(二)
- 元件化開發(二)元件化