日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

让程序在崩溃时体面的退出之SEH

發布時間:2024/4/11 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 让程序在崩溃时体面的退出之SEH 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??????? SEH的全稱是Structured Exception Handling,是Windows操作系統提供的一種異常處理方式。SEH是屬于操作系統的特性,不為特定語言設計,從它的名字就能看出它是一種結構化的異常處理方式。SEH包括了2個部分:終止處理__try/__finally和異常處理__try/__except,下面分別進行介紹。

??????? 終止處理__try/__finally
??????? __try/__finally可以保證無論try塊內的代碼執行結果如何,finally塊內的代碼總會被調用和執行。現在用下面的這個VC++中的控制臺程序來說明。

[cpp] view plaincopy
  • int?_tmain(int?argc,?_TCHAR*?argv[])??
  • {??
  • ????__try??
  • ????{??
  • ????????MessageBox(NULL,?_T("Message?from?'__try'?section"),?_T("Test"),?MB_OK);??
  • ??
  • ????????//?除零,人為的使程序崩潰??
  • ????????//??
  • ????????int?i?=?13;??
  • ????????int?j?=?0;??
  • ????????int?m?=?i?/?j;??
  • ????}??
  • ????__finally??
  • ????{??
  • ????????//?在這里添加處理程序崩潰情況的代碼??
  • ????????//??
  • ??
  • ????????//?這里以彈出一個對話框為例子??
  • ????????//??
  • ????????MessageBox(NULL,?_T("Message?from?'__finally'?section"),?_T("Test"),?MB_OK);??
  • ????}??
  • ??
  • ????MessageBox(NULL,?_T("Funcation?completed"),?_T("Test"),?MB_OK);??
  • ??
  • ????return?0;??
  • }??
  • ??????? 編譯上面的代碼。運行生成的EXE,會彈出下面的對話框。

    ??????? 點擊OK按鈕后,程序會崩潰。

    ??????? 在出現上面這個對話框的時候點擊Cancel,將控制權返還給程序,那么下面的對話框就會彈出。

    ??????? 點擊OK按鈕后,程序正常退出。
    ??????? 由上面的例子可以看出,無論try塊中的代碼會不會出現異常,在程序終止的時候,finally塊中的代碼都會被調用和執行。所以一般情況下,finally塊中的代碼都是用來做一些清理工作和資源的釋放。

    ??????? 異常處理__try/__except
    ??????? __try/__except是用來捕捉異常的,只有當try塊中的代碼出現異常的時候,except塊中的代碼才會被調用和執行。它的語法是這樣的:

    [cpp] view plaincopy
  • __try??
  • {??
  • ????//?guarded?code??
  • }??
  • __except(expression)??
  • {??
  • ?????//?exception?handler?code??
  • }??
  • ??????? 它最大的一個好處就是可以完全控制異常進程。expression的值決定了異常被處理完后,進程該如何執行。下面依然用VC++中的控制臺程序來說明。

    [cpp] view plaincopy
  • int?_tmain(int?argc,?_TCHAR*?argv[])??
  • {??
  • ????__try??
  • ????{??
  • ????????MessageBox(NULL,?_T("Message?from?'__try'?section"),?_T("Test"),?MB_OK);??
  • ??
  • ????????//?除零,人為的使程序崩潰??
  • ????????//??
  • ????????int?i?=?13;??
  • ????????int?j?=?0;??
  • ????????int?m?=?i?/?j;??
  • ????}??
  • ????__except(EXCEPTION_EXECUTE_HANDLER)??
  • ????{??
  • ????????//?在這里添加處理程序崩潰情況的代碼??
  • ????????//??
  • ??
  • ????????//?這里以彈出一個對話框為例子??
  • ????????//??
  • ????????MessageBox(NULL,?_T("Message?from?'__except'?section"),?_T("Test"),?MB_OK);??
  • ????}??
  • ??
  • ????MessageBox(NULL,?_T("Funcation?completed"),?_T("Test"),?MB_OK);??
  • ??
  • ????return?0;??
  • }??
  • ??????? 編譯上面的代碼。運行生成的EXE,會依次彈出下面的對話框。

    ??????? 可以看出,在異常處理代碼被調用執行后(except塊中的代碼),程序繼續可以繼續運行,并正常退出,并沒有崩潰!通過使用__try/__except可以捕捉到任何類型的異常,并保證程序不會崩潰!(想想這是多么的神奇,一個程序永遠不會崩潰!)
    ??????? 下面解釋一下except中表達式各個值的含義:

    EXCEPTION_CONTINUE_SEARCH??????? 異常沒有被處理,繼續向上拋出。如果更上層的代碼沒有異常捕捉機制,程序就會崩潰。
    EXCEPTION_CONTINUE_EXECUTION?? 異常已經被處理,返回異常發生的地方繼續執行。
    EXCEPTION_EXECUTE_HANDLER??????? 異常已經被處理,程序繼續往后執行。

    ??????? 通過上面的例子可以知道,SEH的異常處理跟C++的異常處理不同,C++的try/catch不能控制異常進程,對于異常,要么處理,要么繼續向上拋出。而SEH卻能完全控制異常進程,處理完異常之后,還能決定進該進程如何執行。只要SEH運用得當,編寫一個永不崩潰的應用程序成為可能。但是SEH有一個致命的弱點,那就是它是一種結構化的異常處理,所以不支持面向對象。下面用具體的VC++控制臺程序來說明。

    [cpp] view plaincopy
  • //?一個有函數調用的類??
  • //???
  • class?CrashTest??
  • {??
  • public:??
  • ????CrashTest()?{}??
  • ????~CrashTest()?{}??
  • ??
  • ????void?Test()???
  • ????{???
  • ????????Crash();???
  • ????}??
  • ??
  • private:??
  • ????void?Crash()???
  • ????{???
  • ????????//?除零,人為的使程序崩潰??
  • ????????//??
  • ????????int?i?=?13;??
  • ????????int?j?=?0;??
  • ????????int?m?=?i?/?j;??
  • ????}??
  • };??
  • ??
  • int?_tmain(int?argc,?_TCHAR*?argv[])??
  • {??
  • ????__try??
  • ????{??
  • ????????CrashTest?test;??
  • ????????test.Test();??
  • ????}??
  • ????__except(EXCEPTION_EXECUTE_HANDLER)??
  • ????{??
  • ????????//?在這里添加處理程序崩潰情況的代碼??
  • ????????//??
  • ????}??
  • ??
  • ????return?0;??
  • }??
  • ??????? 上面的代碼不能通過編譯,VC++編譯器會給出這樣的錯誤信息:error C2712: Cannot use __try in functions that require object unwinding。錯誤原因很簡單,try塊內使用了對象。
    ??????? 要想解決這個問題,可以把使用對象的邏輯放到一個函數里,然后在try里調用這個函數,來騙過編譯器。把上面的代碼修改成下面這樣就可以通過編譯。

    [cpp] view plaincopy
  • void?Test()??
  • {??
  • ????CrashTest?test;??
  • ????test.Test();??
  • }??
  • ??
  • int?_tmain(int?argc,?_TCHAR*?argv[])??
  • {??
  • ????__try??
  • ????{??
  • ????????Test();??
  • ????}??
  • ????__except(EXCEPTION_EXECUTE_HANDLER)??
  • ????{??
  • ????????//?在這里添加處理程序崩潰情況的代碼??
  • ????????//??
  • ????}??
  • ??
  • ????return?0;??
  • }?
  • 總結

    以上是生活随笔為你收集整理的让程序在崩溃时体面的退出之SEH的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。