異常處理方法

1. Windows SEH 與 C++ Exception

1)       Windows SEH 結構化異常

結構化異常是Windows 操作系統提供的與語言無關的異常處理機制, SHE使用Win32API中的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=%d/n",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* pExp )

         {

                      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庫

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章