使用异常处理程序

以下示例演示了异常处理程序的使用。

示例 1

以下代码片段使用结构化异常处理来检查两个 32 位整数上的除法运算是否会导致除法错误。 如果发生这种情况,则函数返回 FALSE,否则返回 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;
} 

示例 2

以下示例函数调用 DebugBreak 函数,并使用结构化异常处理来检查断点异常。 如果发生,则函数返回 FALSE,否则返回 TRUE

示例中的筛选器表达式使用 GetExceptionCode 函数在执行处理程序之前检查异常类型。 这样,如果发生某种其他类型的异常,系统就可以继续搜索相应的处理程序。

此外,在异常处理程序的__try块中使用 return 语句不同于在终止处理程序的__try块中使用返回,这会导致__try块的异常终止。 这是异常处理程序中返回语句的有效用法。

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

仅当需要异常类型且故障地址已知时,才从异常筛选器返回EXCEPTION_EXECUTE_HANDLER。 应允许默认异常处理程序处理意外的异常类型和故障地址。

示例 3

下面的示例演示嵌套处理程序的交互。 RaiseException 函数在异常处理程序的受保护的正文中导致异常,该处理程序位于异常处理程序的受保护的正文中。 异常会导致系统评估 FilterFunction 函数,其返回值反过来会导致调用异常处理程序。 但是,在执行异常处理程序块之前,将执行终止处理程序的 __finally 块,因为控制流已离开终止处理程序的 __try 块。

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