Udostępnij za pomocą


Używanie programu obsługi wyjątków

W poniższych przykładach pokazano użycie programu obsługi wyjątków.

W niektórych przykładach użyto funkcji GetExceptionCode w wyrażeniu filtru __except , aby sprawdzić typ wyjątku przed wykonaniem procedury obsługi. Dzięki temu system może kontynuować wyszukiwanie odpowiedniej procedury obsługi, jeśli wystąpi inny typ wyjątku.

Ogólnie rzecz biorąc, zwracaj tylko EXCEPTION_EXECUTE_HANDLER z filtru wyjątku, gdy typ wyjątku jest oczekiwany, a adres błędu jest znany. Należy zezwolić domyślnemu programowi obsługi wyjątków na przetwarzanie nieoczekiwanych typów wyjątków i adresów błędów.

Przykład 1

Poniższy fragment kodu używa strukturalnej obsługi wyjątków do sprawdzenia, czy operacja dzielenia na dwóch 32-bitowych liczbach całkowitych doprowadzi do błędu dzielenia przez zero. W takim przypadku funkcja zwraca FALSE— w przeciwnym razie zwraca TRUE.

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;
} 

Przykład 2

Poniższa przykładowa funkcja wywołuje funkcję DebugBreak i używa obsługi wyjątków strukturalnych, aby wychwycić wyjątek punktu przerwania. W takim przypadku oznacza to, że wyjątek nie został obsłużony przez debuger, a funkcja zwraca wartość FALSE — w przeciwnym razie zwraca wartość TRUE.

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;
}

Przykład 3

W poniższym przykładzie pokazano interakcję zagnieżdżonych programów obsługi. Funkcja RaiseException powoduje wyjątek w zabezpieczonej sekcji procedury obsługi zakończenia, która znajduje się wewnątrz zabezpieczonej sekcji procedury obsługi wyjątków. Wyjątek powoduje, że system ocenia funkcję FilterFunction, której wartość zwracana z kolei powoduje wywołanie procedury obsługi wyjątków. Jednak zanim zostanie wykonany blok obsługi wyjątków, wykonywany jest blok __finally programu obsługi zakończenia, ponieważ przepływ sterowania opuścił blok __try tego programu.

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 
    } 
}