Verwenden eines Ausnahmehandlers

Die folgenden Beispiele veranschaulichen die Verwendung eines Ausnahmehandlers.

Beispiel 1

Das folgende Codefragment verwendet die strukturierte Ausnahmebehandlung, um zu überprüfen, ob ein Divisionsvorgang für zwei ganze 32-Bit-Zahlen zu einem Fehler der Division by Zero führt. Wenn dies der Fall ist, gibt die Funktion FALSE zurück, andernfalls gibt sie TRUE zurück.

BOOL SafeDiv(INT32 dividend, INT32 divisor, INT32 *pResult)
{
    __try 
    { 
        *pResult = dividend / divisor; 
    } 
    __except(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO ? 
             EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
    { 
        return FALSE;
    }
    return TRUE;
} 

Beispiel 2

Die folgende Beispielfunktion ruft die DebugBreak-Funktion auf und verwendet die strukturierte Ausnahmebehandlung, um nach einer Breakpointausnahme zu suchen. Wenn dies der Fall ist, gibt die Funktion FALSE zurück, andernfalls gibt sie TRUE zurück.

Der Filterausdruck im Beispiel verwendet die GetExceptionCode-Funktion , um den Ausnahmetyp vor dem Ausführen des Handlers zu überprüfen. Dadurch kann das System seine Suche nach einem geeigneten Handler fortsetzen, wenn ein anderer Ausnahmetyp auftritt.

Außerdem unterscheidet sich die Verwendung der return-Anweisung im __try Block eines Ausnahmehandlers von der Verwendung der Rückgabe im __try Block eines Beendigungshandlers, was zu einer abnormalen Beendigung des __try-Blocks führt. Dies ist eine gültige Verwendung der return-Anweisung in einem Ausnahmehandler.

BOOL CheckForDebugger()
{
    __try 
    {
        DebugBreak();
    }
    __except(GetExceptionCode() == EXCEPTION_BREAKPOINT ? 
             EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) 
    {
        // No debugger is attached, so return FALSE 
        // and continue.
        return FALSE;
    }
    return TRUE;
}

Geben Sie nur EXCEPTION_EXECUTE_HANDLER aus einem Ausnahmefilter zurück, wenn der Ausnahmetyp erwartet wird und die fehlerhafte Adresse bekannt ist. Sie sollten zulassen, dass der Standard-Ausnahmehandler unerwartete Ausnahmetypen und fehlerhafte Adressen verarbeitet.

Beispiel 3

Das folgende Beispiel zeigt die Interaktion geschachtelter Handler. Die RaiseException-Funktion verursacht eine Ausnahme im bewachten Textkörper eines Beendigungshandlers, der sich im geschützten Text eines Ausnahmehandlers befindet. Die Ausnahme bewirkt, dass das System die FilterFunction-Funktion auswertet, deren Rückgabewert wiederum dazu führt, dass der Ausnahmehandler aufgerufen wird. Bevor der Ausnahmehandlerblock ausgeführt wird, wird jedoch der __finally Block des Beendigungshandlers ausgeführt, da der Ablauf der Steuerung den __try Block des Beendigungshandlers verlassen hat.

DWORD FilterFunction() 
{ 
    printf("1 ");                     // printed first 
    return EXCEPTION_EXECUTE_HANDLER; 
} 
 
VOID main(VOID) 
{ 
    __try 
    { 
        __try 
        { 
            RaiseException( 
                1,                    // exception code 
                0,                    // continuable exception 
                0, NULL);             // no arguments 
        } 
        __finally 
        { 
            printf("2 ");             // this is printed second 
        } 
    } 
    __except ( FilterFunction() ) 
    { 
        printf("3\n");                // this is printed last 
    } 
}