Depeše EXCEPTEX MFC a Win32 strukturovaného výjimky

Překlady článku Překlady článku
ID článku: 167802 - Produkty, které se vztahují k tomuto článku.
Tento článek byl archivován. Je nabízen v takovém stavu, v jakém je, a nebude již nadále aktualizován.
Rozbalit všechny záložky | Minimalizovat všechny záložky

Na této stránce

Souhrn

EXCEPTEX je ukázka znázorňuje techniky soutisku Structured výjimky Win32 a C++ výjimky. Pro C++ výjimky různých helper poskytované funkcí, které ukazují, jak otevřít prolomení více běžně používá třídy výjimku. Pomocné funkce pro výjimky Structured Win32 je součástí, které identifikuje typ vyvolána výjimka Win32.

K dispozici jsou Vám následující soubory ze sekce Ke Stažení:


Exceptex.exe

Další informace o tom, jak stahovat soubory podpory společnosti Microsoft, naleznete v následujícím článku znalostní báze Microsoft Knowledge Base:
119591Jak získat soubory podpory společnosti Microsoft ze serverů služeb online
Microsoft tento soubor zkontroloval na výskyt virů. Společnost Microsoft použila aktuální antivirový software, který byl k dispozici v den uveřejnění tohoto článku. Soubor je uložený na zabezpečených serverech neumožňujících neoprávněné změny souborů.

Další informace

Slučování Win32 a zpracování výjimek C++

Zpracování výjimek C++ a Win32 Structured Exception Handling soutisk výjimky používají jinou syntaxi.
    // 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
    }
				
Fundamental rozdíl, že zpracování výjimek C++ očekává k zachycení instanci typu, zatímco Win32 Structured Exception Handling zachytává pouze tři nepodepsané ints.

Můžete, však sloučit C++ a prostřednictvím funkce _set_se_translator() zpracování výjimek Win32. To způsobí výjimku Win32 předaný funkci popisovač voleb, které mohou zalomit Win32 výjimka informace třídy a "vyvoláním" jej jako C++ výjimku. Při dochází výjimka Win32 a zobrazí se do programu jako výjimky C++ tomu automaticky (viz Exception Handling rozdíly v infoviewer VC 5.0). Toto je provést můžete automaticky Pokud používat makra LOG a související podporují funkce 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);

        ...
    }
				
v tomto případě LogEnable by být volána jednou, brzké v provádění programu a všechny výjimky Win32 aktivovaná by zachycena s C++ syntaxe. EXCEPTEX příklad znázorňuje to pomocí kódu dané výše.

Typy C++ výjimky

Existuje několik kategorií výjimky C++ může být zachycena program MFC-založena:

  • Instance třídy odvozené od jeho MFC CException
  • Instance třídy encapsulating Win32 výjimka
  • Instance z _com_error třídy, která je aktivována Visual C++ 5.0 podporují nativní COM k dispozici prostřednictvím direktiva #import.
Pro každý z těchto EXCEPTEX nabízí funkce nazývá LogException přetížený pro konkrétní typ právě zachytil výjimku. V každém případě vyvolá výjimku ukazatel konkrétní typ obvykle C++ třídy nebo instance. Existují over-loaded verze LogException pro jednotlivé typy C++ výjimek uvedených výše.

Níže je příklad deklarace přetížené funkce LogException, zachytává ukazatel do třídy MFC CException.
    // Crack open and log details of different types of exceptions
    extern void LogException( CException    *e,
                              LPCSTR        lpszTimeStamp,
                              LPCSTR        lpszFile,
                              int           nLine        );
				
LogException také sleduje číslo řádku a název souboru kde makro výjimka byla použita naposledy v zásobníku volání (Pokud použit helper LOG makro).

Každý z těchto pomocné funkce cracks otevřít výjimky a ukládá výsledky pole řetězců, které můžete podle potřeby zpracovat. Funkce pro vypsání obsah tohoto pole řetězců makro TRACE() je LogDisplay().

Zjednodušení zkuste/catch blokuje s Pomocník makra

Littering zkuste/catch bloky kódu lze získat messy po chvíli. Je však možné zjednodušit bloky výjimka prostřednictvím použití makra. EXCEPTEX poskytuje tři makra zjednodušení tohoto procesu a každý nabízí různé funkce protokolování a zpracování výjimek. Každý makra zapsány také pracovat pro 4.X Visual C++ a Visual C++ 5.0, takže jejich musí zkontrolovat verze kompilátoru používáte.

Níže je nejjednodušší makra LOGQ (tichý Exception Handling s žádné protokolování). Očekává, Logická proměnná s názvem bRetVal je k dispozici v kódu. Musí být PRAVDA, že makro může umožnit spuštění kódu mohou vyvolat výjimku a nastaví na FALSE, pokud je aktivována výjimku.
    #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
				
_MSC_VER #ifdef omezuje definice makra být specifické Visual C++ 4.X nebo 5.0. Verze 5.0 obsahuje catch výjimka nově zavedený _com_error (generovaný kód vytvořený z #import).

LOGQ by použít, jak je ukázáno níže:
    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; )
				
nejsou dvě verze maker LOG poskytované EXCEPTEX. Druhé makro LOG používá přetížené pomocníky LogException() popsané výše.
    #define LOGE( f ) try                               \ 
                      {                                 \ 
                          f;                            \ 
                      }                                 \ 
                      catch( CException *e )            \ 
                      {                                 \ 
                          LogException( e,              \ 
                                        __TIMESTAMP__,  \ 
                                        __FILE__,       \ 
                                        __LINE__      );\ 
                      }                                 \ 
                      ...
				
Nevytváří toto makro použít příznak bRetVal. Bude vždy spouštět kód zapouzdřen makro, zachytit výjimky aktivována a jejich obsah protokolu.

Konečné LOG makro EXCEPTEX LOGR, poskytované kombinuje LOGQ a LOGE. Zkontroluje, zda by měla spustit kód a protokolu výjimek, které je aktivována.
    #define LOGR( f ) if( bRetVal == TRUE )                 \ 
                      {                                     \ 
                          try                               \ 
                          {                                 \ 
                              f;                            \ 
                          }                                 \ 
                          catch( CException *e )            \ 
                          {                                 \ 
                              LogException( e,              \ 
                                            __TIMESTAMP__,  \ 
                                            __FILE__,       \ 
                                            __LINE__      );\ 
                              bRetVal = FALSE;              \ 
                          }                                 \ 
                          ...
                        }
				

Jiné užitečné funkce

Ukázka EXCEPTEX poskytuje tři další funkce pomoci zpracování výjimek:
LogDisplay() Vypíše všechny protokolované výjimky mimo prostřednictvím makra TRACE obsah.

LogDisplay (...) Vypíše všechny protokolované výjimky mimo k instanci CListBox obsah.

LogSaveToFile (...) Vypíše obsah všechny protokolované výjimky mimo do souboru.

LOG.H a LOG.CPP

LOG.H a LOG.CPP obsahovat všechny kód v EXCEPTEX popisovač výjimky. Zbytek ukázkové je ukazují makra/funkce nalezeno v LOG.H a LOG.CPP. Tyto dva soubory lze snadno přidat do existujícího projektu a napsané kompilovat buď 4.X Visual C++ nebo vytvoří 5.0 pod ANSI a UNICODE. Jejich použití přidat # zahrnout "log.h" soubory, které budou používat makro LOGE nebo LOGR. Pokud chcete také prolomení Win32 Structured výjimky, je třeba zavolat LogEnable jednou poblíž začátku programu.
   // One time initialization of data
    LogEnable(false);     // false to verbose mode
				
Přidat makro LOG kód, který chcete získat data z výjimky.
   ...
   LOGE(myFunction())
   ...
				
Poznámka oznámil číslo souboru a řádek bude poslední makro LOG v zásobníku. Pokud myFunction() volá myFun1() a myFun2(), bude mít zalomit každé volání funkce s LOG makro pro výstup zobrazení volání, které v došlo k výjimce.

Pravděpodobně není vždy chcete použít LOG maker nebo dokonce LogException() pomocníky obsažené. Tyto jsou nabízeny i pro potřebu a jako well k ukazují zpracování výjimek komplexní a pro protokolování výsledků jakékoli výjimky zachycené. Jejich nejsou poskytovány jako end-all být všechny v každém prostředí výroby zpracování výjimek.

Odstraňování potíží

Následující kód zobrazuje není použití makra helper
    LOGQ( int i = 0; )
    LOGQ( int j = 1 / i; )    // Will this raise a divide by zero?
				
tento kód generuje chyba kompilátoru i pouze definované v oboru první makro LOGQ. Nezapomeňte, že rozšíří LOGQ:
>
    ...
    try
    {
        int i = 0;
    }
    ...

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

/ W4 a #import

Pokud používáte příznak /W4 v #import a Visual C++, uvidíte 8 upozornění generovaných vypnout soubory začlenění využívajícího #import.
comutil.h(905): upozornění C4310: přetypování zkrátí konstantní hodnotu
comutil.h(928): upozornění C4310: přetypování zkrátí konstantní hodnotu
comutil.h(1030): upozornění C4310: přetypování zkrátí konstantní hodnotu
comutil.h(1281): upozornění C4310: přetypování zkrátí konstantní hodnotu
comutil.h(1307): upozornění C4310: přetypování zkrátí konstantní hodnotu
comutil.h(1476): upozornění C4310: přetypování zkrátí konstantní hodnotu
comdef.h(242): upozornění C4244: 'vrátit: Převod z 'int' do 'nepodepsané krátkém', možnou ztrátu dat
Tyto chybové zprávy mohou být ignorovány a by nemělo mít vliv váš kód.

Další informace

Následující téma infoviewer VC ++ 5.0 prezentovat dobře Úvod k zpracování techniky výjimek:
Zpracování výjimek: Časté otázky
mk:@ivt:vccore/F26/D2A/S31BE4.HTM

Rozdíly zpracování výjimek
mk:@ivt:vccore/F26/D2B/S4CC99.HTM
Následující článek demonstruje techniky, které by bylo možné rozbalte ukázkové EXCEPTEX zpracování výjimek DAO SDK.
152695Jak zachytit a dešifrovat DAO systémem SDK výjimky
Definitivní zdroj na Win32 Exception Handling lze nalézt v:

"Rozšířené Windows" podle Petra Dobešová Richter ISBN: 1-57231-548-2

Vlastnosti

ID článku: 167802 - Poslední aktualizace: 1. února 2014 - Revize: 3.2
Informace v tomto článku jsou určeny pro produkt:
  • Microsoft Visual C++ 4.2 Enterprise Edition
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 4.0 Standard Edition
  • Microsoft Visual C++ 4.1 Subscription
  • Microsoft Visual C++ 4.2 Professional Edition
  • Microsoft Visual C++ 5.0 Professional Edition
Klíčová slova: 
kbnosurvey kbarchive kbmt kbdownload kbdatabase kbfile kbsample KB167802 KbMtcs
Strojově přeložený článek
Důležité: Tento článek byl přeložen pomocí software společnosti Microsoft na strojový překlad, ne profesionálním překladatelem. Společnost Microsoft nabízí jak články přeložené překladatelem, tak články přeložené pomocí software na strojový překlad, takže všechny články ve Znalostní databázi (Knowledge Base) jsou dostupné v češtině. Překlad pomocí software na strojový překlad ale není bohužel vždy dokonalý. Obsahuje chyby ve skloňování slov, skladbě vět, nebo gramatice, podobně jako když cizinci dělají chyby při mluvení v češtině. Společnost Microsoft není právně zodpovědná za nepřesnosti, chyby nebo škody vzniklé chybami v překladu, nebo při použití nepřesně přeložených instrukcí v článku zákazníkem. Společnost Microsoft aktualizuje software na strojový překlad, aby byl počet chyb omezen na minimum.
Projděte si také anglickou verzi článku:167802

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