Escrever um filtro de exceção
Você pode manipular uma exceção por saltar para o nível de manipulador de exceção ou continuando a execução.Em vez de usar o código do manipulador de exceção para lidar com a exceção e caindo por meio, você pode usar filtro para limpar o problema e em seguida, retornando – 1, retomar fluxo normal sem limpar a pilha.
Observação |
---|
Algumas exceções não podem ser continuadas.Se filtro for avaliada como – 1 para tal exceção, o sistema gera uma nova exceção.Quando você chama RaiseException, você determina se a exceção continuará. |
Por exemplo, o código a seguir usa uma função de chamada a filtro expressão: esta função lida com o problema e, em seguida, retorna – 1 para retomar o fluxo normal de controle:
// exceptions_Writing_an_Exception_Filter.cpp
#include <windows.h>
int main() {
int Eval_Exception( int );
__try {}
__except ( Eval_Exception( GetExceptionCode( ))) {
;
}
}
void ResetVars( int ) {}
int Eval_Exception ( int n_except ) {
if ( n_except != STATUS_INTEGER_OVERFLOW &&
n_except != STATUS_FLOAT_OVERFLOW ) // Pass on most exceptions
return EXCEPTION_CONTINUE_SEARCH;
// Execute some code to clean up problem
ResetVars( 0 ); // initializes data to 0
return EXCEPTION_CONTINUE_EXECUTION;
}
Ele é uma boa idéia usar uma chamada de função na filtro expressão sempre que filtro precisa fazer algo complexo.Avaliar a expressão faz a execução da função, nesse caso, Eval_Exception.
Observe o uso de GetExceptionCode para determinar a exceção.Você deve chamar essa função dentro do próprio filtro.Eval_Exceptionnão é possível chamar GetExceptionCode, mas ele deve ter o código de exceção passado para ele.
Esse manipulador passa o controle para outro manipulador, a menos que a exceção é um inteiro ou um estouro de ponto flutuante.Se for, o manipulador chama uma função (ResetVars é apenas um exemplo, não é uma função de API) para redefinir algumas variáveis globais.Instrução-bloco-2, que neste exemplo está vazio, nunca possam ser executados porque Eval_Exception nunca retorna EXCEPTION_EXECUTE_HANDLER (1).
O uso de uma chamada de função é uma boa técnica de finalidade geral para lidar com expressões de filtro complexo.Dois outros recursos de linguagem c são úteis são:
O operador condicional
O operador de vírgula
O operador condicional é freqüentemente útil, porque ele pode ser usado para verificar um código de retorno específico e, em seguida, retornar um dos dois valores diferentes.Por exemplo, o filtro no código a seguir reconhece a exceção, somente se a exceção é STATUS_INTEGER_OVERFLOW:
__except( GetExceptionCode() == STATUS_INTEGER_OVERFLOW ? 1 : 0 ) {
A finalidade do operador condicional nesse caso é principalmente oferecer esclarecimento, porque o código a seguir produz os mesmos resultados:
__except( GetExceptionCode() == STATUS_INTEGER_OVERFLOW ) {
O operador condicional é mais útil em situações onde você pode deseja que o filtro a ser avaliada como – 1, EXCEPTION_CONTINUE_EXECUTION.
O operador vírgula permite realizar várias operações independentes dentro de uma única expressão.O efeito é aproximadamente de executar várias instruções e, em seguida, retornando o valor da última expressão.Por exemplo, o código a seguir armazena o código de exceção em uma variável e, em seguida, testa-lo:
__except( nCode = GetExceptionCode(), nCode == STATUS_INTEGER_OVERFLOW )