EXCEPTEX トラップ MFC、Win32 構造化例外

文書翻訳 文書翻訳
文書番号: 167802
すべて展開する | すべて折りたたむ

目次

概要

EXCEPTEX のテクニックを示すサンプルです。Win32 構造化例外と C++ 例外処理の両方をトラップします。C++ の場合解読する方法を示すさまざまなヘルパー関数の例外が用意されています一般的に使用される例外クラスを開きます。Win32 の例外が構成されて、Win32 例外の種類を識別するには、ヘルパー関数をされてスローされます。

は、次のファイルがマイクロソフト ・ ダウンロードからダウンロード可能します。センター:


Exceptex.exe

方法の追加についてマイクロソフトのサポート ファイルをダウンロードするには、表示するのには、次の資料番号をクリックします。資料は、マイクロソフト サポート技術。
119591 オンライン サービスからマイクロソフトのサポート ファイルを入手する方法
マイクロソフトは、このファイルのウイルスをスキャンしました。Microsoft は、最も使用されます。日付が現在のウイルス検出ソフトウェア、ファイル送信されました。ファイルにするのに役立つセキュリティが強化されたサーバーに格納されます。ファイルに許可されていない変更を防ぐ。

詳細

Win32 および C++ 例外処理を結合します。

C++ 例外処理と Win32 構造化例外処理例外をトラップするのにには、同じ構文を使用します。
    // C++ Exception Handler
    try
    {
        // Do something that may raise an exception
    }
    catch( <class name> <instance of class> )
    {
        // handle exception
    }

    // Win32 Structured Exception Handler
    __try
    {
        // Do something that may raise an exception
    }
    __except( expression )
    {
        // handle exception
    }
				
予測に根本的な違い、C++ 例外処理対し、型のインスタンスをキャッチする Win32 構造化例外処理3 つの符号なし整数値をキャッチします。

ただし、両方の C++ を差し込むことができます。Win32 の _set_se_translator() 関数で処理する例外とします。これが任意のハンドラー関数に渡す、Win32 例外、クラスでは、Win32 の例外情報をラップして"は、C++ で throw"例外。Win32 の例外が発生すると、自動的に開始し、プログラムは C++ 例外としてシームレスに表示されます (「例外処理」を参照違いは、VC 5.0 と、infoviewer)。これが自動場合行われます関連サポート Log()、ログ マクロを使用して機能します。
    // Class for containing information on a Win32 Structured Exception
    class SEH_Exception {
    private:
        SEH_Exception() {}
        unsigned int m_uSECode;
    public:
        SEH_Exception(unsigned int uSECode) : m_uSECode(uSECode) {}
        ~SEH_Exception() {}
        unsigned int getSeHNumber() { return m_uSECode; }
    };

    // Handler function that passes on Win32 Exception information in the
    // C++ class SEH_Exception
    void MappingSEHtoCPPExceptions( unsigned int uExceptionCode,
                                                  _EXCEPTION_POINTERS* )
    {
        throw SEH_Exception( uExceptionCode );
    }

    // Initialize Exception Handling
    void LogEnable( ... )
    {
        // Set Win32 Exceptions to be handled as C++ typed exceptions
        _set_se_translator(MappingSEHtoCPPExceptions);

        ...
    }
				
この例では、LogEnable と、早くプログラムでのということになりますC++ 構文で実行、および発生した Win32 例外キャッチできませんでした。は、EXCEPTEX サンプルは上記のコードを使用してこれを示します。

[C++ の例外の種類

C++ の例外をキャッチすることができますのいくつかのカテゴリがあります。MFC によってプログラムをベース。

  • クラスのインスタンスは MFC からの派生CException
  • Win32 をカプセル化するクラスのインスタンス例外
  • 発生して Visual クラスの _com_error のインスタンスC 5.0 ネイティブ COM サポート、#import ディレクティブによって利用できます。
これらの各関数と呼ばれる EXCEPTEX を提供します。LogException は、特定の種類の例外をキャッチするをオーバー ロードします。でいずれの場合も、1 つ、または、特定の型のポインターには例外が発生、通常、C++ クラスです。各 LogException の over-loaded のバージョンがあります。C++ の上記の例外の種類の。

次の例に示しますポインターをキャッチする、オーバー ロードされた LogException 関数の宣言MFC の CException クラスにします。
    // Crack open and log details of different types of exceptions
    extern void LogException( CException    *e,
                              LPCSTR        lpszTimeStamp,
                              LPCSTR        lpszFile,
                              int           nLine        );
				
LogException は、ファイル名と行番号も追跡は、例外マクロ最後のコール スタック (ヘルパー ログで使用する場合は、使用されました。マクロ)。

このヘルパー関数の亀裂オープン例外のと結果、必要に応じて処理する文字列の配列を格納します。は、関数を文字列配列に、TRACE() マクロの内容をダンプします。LogDisplay()。

ヘルパー マクロ ブロックの try と catch を簡素化

Try または catch ブロックのコードを littering ことができます取得後の煩雑なしばらくの間。ただし、例外ブロックを使用して簡略化することが可能です。マクロ。EXCEPTEX はこのプロセスを簡素化する 3 つのマクロおよび各提供します。例外のログ記録と処理に対して異なる機能を提供しています。それぞれのマクロは、Visual C 4.X および Visual C 5.0 のために動作するためにも書き込まれます使用しているコンパイラのバージョンを確認する必要があります。

次のとおりです。最も簡単な (サイレント例外処理ログを記録しない) LOGQ マクロします。そのbRetVal という名前のブール型変数がコード内で使用可能であるとします。そのマクロが発生可能性があります。、コードの実行をできるように true を指定する必要があります。例外が発生し、設定して false を指定するには、例外が発生した場合。
    #if _MSC_VER < 1100    // For version VC++ 4.2 or earlier

        #define LOGQ( f ) if( bRetVal == TRUE )                \ 
                          {                                    \ 
                             try                               \ 
                             {                                 \ 
                                 f;                            \ 
                             }                                 \ 
                             catch( CException *e )            \ 
                             {                                 \ 
                                bRetVal = FALSE;               \ 
                                 e->Delete();                  \ 
                             }                                 \ 
                             catch( SEH_Exception )            \ 
                             {                                 \ 
                                bRetVal = FALSE;               \ 
                             }                                 \ 
                             catch(...)                        \ 
                             {                                 \ 
                                bRetVal = FALSE;               \ 
                             }                                 \ 
                          }

    #else

        #define LOGQ( f ) if( bRetVal == TRUE )                \ 
                          {                                    \ 
                             try                               \ 
                             {                                 \ 
                                f;                             \ 
                             }                                 \ 
                             catch( CException *e )            \ 
                             {                                 \ 
                                bRetVal = FALSE;               \ 
                                e->Delete();                   \ 
                             }                                 \ 
                             catch( _com_error )               \ 
                             {                                 \ 
                                bRetVal = FALSE;               \ 
                              }                                \ 
                             catch( SEH_Exception )            \ 
                             {                                 \ 
                                bRetVal = FALSE;               \ 
                             }                                 \ 
                             catch(...)                        \ 
                             {                                 \ 
                                bRetVal = FALSE;               \ 
                             }                                 \ 
                          }

    #endif
				
#Ifdef _MSC_VER のマクロ定義を制限します。Visual C 4.X または 5.0 のどちらかを特定します。バージョン 5.0 の点が含まれています。新たに導入された _com_error 例外 (から作成されたコードを生成します。#import)。

次に示すように、LOGQ を使用します。
    int     i = 0;
    int     j;
    BOOL    bRetVal = TRUE;

    // This code is not safe
    j = 1 / i;        // Raises Win32 Divide By Zero exception

    // This code is safe
    LOGQ( j = 1 / i; )
				
EXCEPTEX によって提供されるログ マクロの 2 つのバージョンがあります。記載されている、オーバー ロードされた LogException() ヘルパー ログの 2 番目のマクロが使用されます。上。
    #define LOGE( f ) try                               \ 
                      {                                 \ 
                          f;                            \ 
                      }                                 \ 
                      catch( CException *e )            \ 
                      {                                 \ 
                          LogException( e,              \ 
                                        __TIMESTAMP__,  \ 
                                        __FILE__,       \ 
                                        __LINE__      );\ 
                      }                                 \ 
                      ...
				
このマクロを利用しない、フラグ bRetVal を使用します。それは常にされます。マクロによってカプセル化されたコードを実行、発生した例外をキャッチおよびログイン内容。

EXCEPTEX は LOGR によって提供される最後のログ マクロLOGQ と LOGE の両方を組み合わせたものです。これは、コードを実行するかを確認するチェックし、発生した例外をログに記録します。
    #define LOGR( f ) if( bRetVal == TRUE )                 \ 
                      {                                     \ 
                          try                               \ 
                          {                                 \ 
                              f;                            \ 
                          }                                 \ 
                          catch( CException *e )            \ 
                          {                                 \ 
                              LogException( e,              \ 
                                            __TIMESTAMP__,  \ 
                                            __FILE__,       \ 
                                            __LINE__      );\ 
                              bRetVal = FALSE;              \ 
                          }                                 \ 
                          ...
                        }
				

その他の便利な機能

EXCEPTEX サンプルを支援する 3 つ関数が用意されています例外処理:
LogDisplay() ログに記録されたすべての例外がトレース マクロ経由での内容をダンプします。

LogDisplay (...) ログからすべての例外のインスタンスの内容をダンプします。CListBox。

LogSaveToFile (...) ログに記録されたすべての例外をファイルの内容をダンプします。

ログです。H およびログします。CPP

ログです。H およびログします。CPP は、EXCEPTEX を処理するコードの記述します。例外。サンプルの残りの部分はマクロと関数を説明するためにはログに記録します。H およびログします。CPP。これら 2 つのファイルに簡単に、既存に追加します。プロジェクト、および Visual C 4.X または 5.0 でコンパイル.UNICODE と ANSI の両方をビルドします。#] を追加して、それらを使用するには、"log.h"ファイルを含めるLOGE または LOGR マクロを使用するされます。場合は、Win32 をクラックします。例外を構成しますまた、LogEnable 回の先頭近くに呼び出す必要があります。プログラム。
   // One time initialization of data
    LogEnable(false);     // false to verbose mode
				
ログ マクロ、例外データを取得するコードを追加します。
   ...
   LOGE(myFunction())
   ...
				
ファイルと行番号が報告された最後のログ マクロになりますのでご注意スタックにします。MyFun1() と myFun2()、myFunction() を呼び出す場合は、する必要があります。関数を呼び出すたびにログ マクロを呼び出すを表示するのには、出力をラップします。例外を発生します。

常に、ログを使用する必要がないです。マクロまたはが提供されるため、LogException() ヘルパーもします。それら両方として提供されています。利便性と包括的な例外処理をデモンストレーションするも例外の結果を記録するをキャッチします。として提供されていません。end-all、されるすべての例外処理のすべての本番環境での。

トラブルシューティング

次のコードは、ヘルパー マクロを使用しないようにする方法を示しています。
    LOGQ( int i = 0; )
    LOGQ( int j = 1 / i; )    // Will this raise a divide by zero?
				
I はスコープ内でのみ定義されているように、コンパイラ エラー コードが生成されます。最初の LOGQ マクロの。LOGQ に展開することに注意してください。
>
    ...
    try
    {
        int i = 0;
    }
    ...

    ...
    try
    {
        int j = 1 / i;  // error C2065: 'i' : undeclared
    }
    ...
				

/W4 および #import

/W4 フラグには、Visual C および #import を使用している場合を行います#import を使用して、インクルード ファイルから生成された 8 の警告を参照してください。
comutil.h(905): C4310 警告: キャスト定数値が切り捨てられます
comutil.h(928): C4310 警告: キャスト定数値が切り捨てられます
comutil.h(1030): C4310 警告: キャスト定数値が切り捨てられます
comutil.h(1281): C4310 警告: キャスト定数値が切り捨てられます
comutil.h(1307): C4310 警告: キャスト定数値が切り捨てられます
comutil.h(1476): C4310 警告: キャスト定数値が切り捨てられます
comdef.h(242): C4244 警告: 'return': 'int' への変換'署名短い'、可能性のあるデータが失われる
これらのエラー メッセージを無視していないに影響を与える必要があります、コードです。

詳細については

Vc++ 5.0 と、infoviewer トピック提示するな例外処理テクニックを紹介します。
例外処理: よく寄せられる質問
mk:@ivt:vccore/F26/D2A/S31BE4。HTM ファイル

例外処理の違い
mk:@ivt:vccore/F26/D2B/S4CC99。HTM ファイル
れる可能性のある技術の次の資料を示しています。EXCEPTEX サンプル DAO SDK の例外を処理するを展開します。
152695キャッチし、DAO SDK ベースの例外を解読する方法
Win32 例外を処理するのには、源をご覧ください。

"高度な Windows"で、Jeffrey Richter の ISBN 1-57231-548-2

プロパティ

文書番号: 167802 - 最終更新日: 2011年7月5日 - リビジョン: 5.0
キーワード:?
kbdownload kbdatabase kbfile kbsample kbmt KB167802 KbMtja
機械翻訳の免責
重要: このサポート技術情報 (以下「KB」) は、翻訳者による翻訳の代わりに、マイクロソフト機械翻訳システムによって翻訳されたものです。マイクロソフトは、お客様に、マイクロソフトが提供している全ての KB を日本語でご利用いただけるように、翻訳者による翻訳 KB に加え機械翻訳 KB も提供しています。しかしながら、機械翻訳の品質は翻訳者による翻訳ほど十分ではありません。誤訳や、文法、言葉使い、その他、たとえば日本語を母国語としない方が日本語を話すときに間違えるようなミスを含んでいる可能性があります。マイクロソフトは、機械翻訳の品質、及び KB の内容の誤訳やお客様が KB を利用されたことによって生じた直接または間接的な問題や損害については、いかなる責任も負わないものとします。マイクロソフトは、機械翻訳システムの改善を継続的に行っています。
英語版 KB:167802
Microsoft Knowledge Base の免責: Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。
サポート期間が終了した「サポート技術情報」資料に関する免責事項
この資料は、マイクロソフトでサポートされていない製品について記述したものです。そのため、この資料は現状ベースで提供されており、今後更新されることはありません。

フィードバック

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com