다음 예제에서는 예외 처리기를 사용하는 방법을 보여 줍니다.
일부 예제에서는 __except 필터 식 내에서 GetExceptionCode 함수를 사용하여 처리기를 실행하기 전에 예외 유형을 확인합니다. 이렇게 하면 다른 유형의 예외가 발생하는 경우 시스템에서 적절한 처리기에 대한 검색을 계속할 수 있습니다.
일반적으로 예외 유형이 예상되고 오류 주소가 알려진 경우에만 예외 필터에서 EXCEPTION_EXECUTE_HANDLER 반환합니다. 기본 예외 처리기가 예기치 않은 예외 유형 및 오류 주소를 처리하도록 허용해야 합니다.
예제 1
다음 코드 조각에서는 구조적 예외 처리를 사용하여 두 32비트 정수에 대한 나누기 작업으로 인해 0으로 나누기 오류가 발생하는지 확인합니다. 이 경우 함수는 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를 반환합니다.
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;
}
예제 3
다음 예제에서는 중첩된 처리기의 상호 작용을 보여 줍니다. RaiseException 함수는 예외 처리기의 보호된 본문 안에 있는 종료 처리기의 보호된 본문에서 예외를 발생시킵니다. 예외로 인해 시스템에서 FilterFunction 함수를 평가합니다. 이 함수의 반환 값으로 인해 예외 처리기가 호출됩니다. 그러나 예외 처리기 블록을 실행하기 전에 제어 흐름이 종료 처리기의 __try 블록을 떠났기 때문에 종료 처리기의 __finally 블록이 실행됩니다.
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
}
}