Windows核心编程 第25章 未处理异常和C ++异常(下)
? ? 這一節東西比較少,本應該歸并在上一節里,但是昨天太晚了。就先把那些東西分為上了。這節里面就一個問題,C++異常與結構性異常的對比(try和__try的區別):
C++異常與結構性異常的對比
????S?E?H是可用于任何編程語言的操作系統設施,而異常處理只能用于編寫
C?+?+代碼。如果你在編寫C?+?+程序,你應該使用C?+?+異常處理而不是結構化異常處理。理由是C?+?+異常處理是語言的一部分,編譯器知道?C?+?+類對象是什么。也就是說編譯器能夠自動生成代碼來調用C?+?+對象析構函數,保證對象的清除。
????但是也應該知道,Microsoft?Visual?C++編譯器已經利用操作系統的結構化異常處理實現了C?+?+異常處理。所以當你建立一個?C++?try塊時,編譯器就生成一個?S?E?H_?_t?r?y塊。一個C?+?+c?a?t?c?h測試變成一個S?E?H異常過濾器,并且c?a?t?c?h中的代碼變成S?E?H_?_e?x?c?e?p?t塊中的代碼。實際上,當你寫一條C++?throw語句時,編譯器就生成一個對Wi?n?d?o?w?s的R?a?i?s?e?E?x?c?e?p?t?i?o?n函數的調用。用于t?h?r?o?w語句的變量傳遞給R?a?i?s?e?E?x?c?e?p?t?i?o?n作為附加的參數。
? ? 下面的代碼段可以使上面的敘述更清楚一些。左邊的函數使用?C?+?+異常處理,右邊的函數說明了C?+?+編譯器如何生成等價的結構化異常處理。
? ? 你可能注意到上面代碼中一些有趣的細節。首先,函數?R?a?i?s?e?E?x?c?e?p?t?i?o?n的調用使用了異常代碼0?x?E?0?6?D?7?3?6?3。這是由Visual?C++的開發人員選擇的軟件異常代碼,在引發C?+?+異常時使用。事實上你可以驗證這一點,方法是打開調試程序的?E?x?c?e?p?t?i?o?n?s對話框,滾動到異常列表的底部,見圖2?5?-?1?5。
? ? 當引發了C?+?+異常時,總要使用E?X?C?E?P?T?I?O?N?_?N?O?N?C?O?N?T?I?N?U?E?A?B?L?E標志。C?+?+異常不能被重新執行。對于診斷C?+?+異常的過濾器,如果返回E?X?C?E?P?T?I?O?N?_?C?O?N?T?I?N?U?E?_?E?X?E?C?U?T?I?O?N,那將是個錯誤。實際上,我們看一看上面程序段右邊函數中的?_?_?e?x?c?e?p?t過濾器,就會發現它只能計算成E?X?C?E?P?T?I?O?N?_?E?X?E?C?U?T?E?_?H?A?N?D?L?E?R或E?X?C?E?P?T?I?O?N?_?C?O?N?T?I?N?U?E?_?S?E?A?R?C?H。
? ? 傳遞到R?a?i?s?e?E?x?c?e?p?t?i?o?n的其余參數是用來作為一種機制,用于實際引發指定的變量。被引發的變量信息是如何傳遞到?R?a?i?s?e?E?x?c?e?p?t?i?o?n的,這一點沒有公開。但不難想像編譯器的開發人員可以實現這一點。
? ? 最后要指出的是_?_?e?x?c?e?p?t過濾器。這個過濾器的用途是將t?h?r?o?w變量的數據類型同用于C?+?+c?a?t?c?h語句的變量類型相比較。如果數據類型相同,過濾器返回?E?X?C?E?P?T?I?O?N?_?E?X?E?C?U?T?E?_H?A?N?D?L?E?R,導致c?a?t?c?h塊(_?_?e?x?c?e?p?t塊)中的語句執行。如果數據類型不同,過濾器返回E?X?C?E?P?T?I?O?N?_?C?O?N?T?N?U?E?_?S?E?A?R?C?H,導致c?a?t?c?h過濾器上溯要計算的調用樹。
正常情況下,C?+?+異常處理不能使程序從硬件異常中恢復,硬件違規就是存取違規或零作除數這種異常。但微軟已經對其編譯器增加了這種支持能力。例如,下面的代碼可以防止進程不正常地結束:(VS默認是Release可以,Debug的話還是會掉相關處理函數,然后彈異常窗)
????同時catch里面還可以細分,就是判斷異常類型然后做相應處理:Visuad?C++有一種機制可以實現這一點。你需要做的是建立你自己的C?+?+類,在代碼中用來標識結構性異常。這里是一個例子:
? ? 在每個線程的進入點函數里,調用靜態成員函數?M?a?p?S?E?t?o?C?E。這個函數調用C運行時函數_?s?e?t?_?s?e?_?t?r?a?n?s?l?a?t?o?r,并傳遞?C?S?E類的?Tr?a?n?s?l?a?t?e?S?E?t?o?C?E函數的地址作為參數。通過調用_?s?e?t?_?s?e?_?t?r?a?n?s?l?a?t?o?r,告訴C?+?+運行時系統,在結構性異常發生時調用?Tr?a?n?s?l?a?t?e?S?E?t?o?C?E函數。這個函數構造一個C?S?E類對象并初始化兩個數據成員以包含有關異常的?C?P?U獨立和C?P?U依賴的信息。在構造了C?S?E對象之后,它就被引發,如同任何正常的變量可被引發一樣。現在你的?C?+?+代碼可以通過捕獲一個這類的變量來處理結構性異常。
下面是如何捕獲這個C?+?+對象的例子。
?
額...講道理是應該先輸出個111然后輸出222的吧,結果是直接崩潰了。
總結
以上是生活随笔為你收集整理的Windows核心编程 第25章 未处理异常和C ++异常(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows PE 重定位表编程(枚举
- 下一篇: Windows核心编程 第26章 窗口消