異常處理方法 (轉)

amyz發表於2007-11-25
異常處理方法 (轉)[@more@]

異常處理方法:namespace prefix = o ns = "urn:schemas--com::office" />

1. SEH 與 C++ Exception

1)  Windows SEH 結構化異常

結構化異常是Windows操作提供的與語言無關的異常處理機制, SHE使用中的RaiseException()來丟擲異常,在VC中使用關鍵字__try和關鍵字__except來捕獲,並用宏函式GetExceptionCode和GetExceptionInfo來獲取捕獲的異常由什麼原因產生,和產生異常時環境狀態。__finally關鍵字保證無論是否發生異常,finally程式碼段都會被。

SHE使用示例程式碼

int ECode;

   __try


  {


   __try


  {


   RaiseException(1,  // 丟擲異常碼為1的SEH異常


    0,   


   0, NULL);   // 沒有引數


    }


__finally


{


 printf("2 ");   // 不管是否有異常,必定會執行的程式碼


}


 }


__except (ECode=GetExceptionCode())


 {


 printf("發生異常,Code=%dn",ECode);  // 捕獲異常後執行的程式碼 ;


  }


輸出結果:

2發生異常,Code=1

2)  C++Exception

C++標準也提供了一種異常處理機制,透過使用try,catch,throw關鍵字來表達,在C++異常可以透過throw函式來丟擲簡單變數,複雜變數與異常,與Windows異常相比,異常物件可以給開發者提供更多的資訊。

try


{


  //正常程式碼


。。。


throw CExcetion();


。。。


}


catch (CException* e)


  {


  //處理異常程式碼


  }


3)  SEH 到 C++異常的轉換

在同一個中,如果使用WIN32API它會丟擲SHE,使用C++庫函式,它們又會丟擲C++異常,Win32API和C++函式混和使用時如果使用兩種異常捕獲機制時,使用起來會影響程式的可讀性,因此C++執行庫提供了_set_se_translator函式,在SHE異常發生時透過回撥方式來轉換SEH異常為C++異常。在此提供一個轉換的宏來實現轉換。

轉換宏的程式碼:

#define INSTALL_SEHCONVERT() ExceptionConvert ecExceptionConvert

class SEHException

{

private:

    unsigned int nSE;

public:

    SEHException() {}

  SEHException( unsigned int n ) : nSE( n ) {}

    ~SEHException() {}

  unsigned int getSeNumber() { return nSE; }

};

class ExceptionConvert

{

public:

  ExceptionConvert(){OldFanc = _set_se_translator(trans_func); }

  ~ExceptionConvert(){_set_se_translator(OldFanc); }

private:

    static void trans_func( unsigned int u, EXCEPTION_POINTERS* pE)

  {

      throw SEHException(u);

  }

  _se_translator_function OldFanc;

};

使用上面INSTALL_SEHCONVERT宏後就可以使用如下程式碼來捕獲SHE異常了

INSTALL_SEHCONVERT();

Try

{

  …

}

catch(SEHException &seh){

  …

}

2. 同步異常與非同步異常

1) VC的C++ Exception 採用兩種捕獲異常:同步模式和非同步模式。VC的工程的版本預設使用非同步模式,工程的釋出版本預設使用同步模式。在同步模式下,VC的假定程式碼中只有在顯示使用throw和函式的時候才會引發異常,因此,在同步模式下,VC編譯出的程式碼比較小,但在這種模式下,try-catch對不能捕獲訪問異常與算術除零異常等。在非同步模式下,VC的編譯器為try塊內的每一條語句生成異常捕獲程式碼,在這種情況下,他能夠捕獲全部的異常,還能保證棧上物件在解棧中正確釋放。為了要在發行版本中也能夠捕獲全部異常就需要開啟非同步模式,但代價是程式編譯出程式碼變大,執行速度變慢。

2)編譯選項:

同步模式的編譯選項為/EHs或者/GX(等同於/EHsc)

非同步模式的編譯選項為/EHa

3. 多執行緒下的異常捕獲

在建立執行緒並執行執行緒的函式中把建立執行緒的程式碼放在try塊中並不會捕獲到執行緒函式中發生的異常,執行緒函式中發生的異常只能線上程函式中捕獲。並且每一個執行緒都需要自己的SHE轉換宏。轉換宏可以放線上程函式的開始部分

4.參考MSDN庫


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-984613/,如需轉載,請註明出處,否則將追究法律責任。