Compartilhar via


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çãoObservaçã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 )

Consulte também

Referência

Escrever um manipulador de exceção

(C++) de manipulação de exceção estruturada