Interceptações EXCEPTEX MFC e Win32 estruturado exceções

IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.

Clique aqui para ver a versão em Inglês deste artigo: 167802
Aviso de Isenção de Responsabilidade sobre Conteúdo do KB Aposentado
Este artigo trata de produtos para os quais a Microsoft não mais oferece suporte. Por esta razão, este artigo é oferecido "como está" e não será mais atualizado.
Sumário
EXCEPTEX é um exemplo que demonstra técnicas para ajuste de registro tanto Win32 exceções estruturada de exceções do C++. Para C++ exceções, auxiliar várias funções são fornecidas que demonstram como violar abrir mais comumente usado classes de exceção. Para exceções estruturada do Win32, uma função auxiliar é fornecida que identifica o tipo de exceção Win32 gerada.

Os seguintes arquivos estão disponíveis para download no Centro de download da Microsoft:


Exceptex.exe

Para obter informações adicionais sobre como baixar arquivos de suporte da Microsoft, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
119591Como obter arquivos de suporte da Microsoft a partir de serviços online
Microsoft examinou esse arquivo em busca de vírus. Microsoft utilizou o mais recente software de detecção de vírus que estava disponível na data em que o arquivo foi publicado. O arquivo é armazenado em servidores com segurança avançada que ajudam a evitar qualquer alteração não autorizada no arquivo.

Mais Informações

Mesclando Win32 e manipulação de exceção do C++

Manipulação de exceção de C++ e Win32 Structured Exception Handling usam uma sintaxe diferente para interceptar exceções.
    // C++ Exception Handler    try    {        // Do something that may raise an exception    }    catch( <class name> <instance of class> )    {        // handle exception    }    // Win32 Structured Exception Handler    __try    {        // Do something that may raise an exception    }    __except( expression )    {        // handle exception    }				
o fundamentais diferença sendo que a manipulação de exceção de C++ espera capturar uma instância de um tipo, enquanto Win32 Structured Exception Handling captura somente três ints não assinados.

No entanto, você pode mesclar C++ e exceção Win32 manipulação por meio da função _set_se_translator(). Isso faz com que uma exceção Win32 a ser passada para a função de manipulador de sua escolha, que pode quebrar automaticamente informações de exceção do Win32 em uma classe e "throw-" como um C++ exceção. Isso acontece automaticamente quando uma exceção Win32 ocorre e aparece diretamente para o programa como uma exceção de C++ (consulte exceção manipulação diferenças em infoviewer VC 5.0). Este é feito para você automaticamente se você usar as macros LOG e relacionada oferece suporte a funções Log().
    // Class for containing information on a Win32 Structured Exception    class SEH_Exception {    private:        SEH_Exception() {}        unsigned int m_uSECode;    public:        SEH_Exception(unsigned int uSECode) : m_uSECode(uSECode) {}        ~SEH_Exception() {}        unsigned int getSeHNumber() { return m_uSECode; }    };    // Handler function that passes on Win32 Exception information in the    // C++ class SEH_Exception    void MappingSEHtoCPPExceptions( unsigned int uExceptionCode,                                                  _EXCEPTION_POINTERS* )    {        throw SEH_Exception( uExceptionCode );    }    // Initialize Exception Handling    void LogEnable( ... )    {        // Set Win32 Exceptions to be handled as C++ typed exceptions        _set_se_translator(MappingSEHtoCPPExceptions);        ...    }				
nesse caso, LogEnable deve ser chamado uma vez, desde o início na execução do programa, e quaisquer exceções Win32 geradas podem ser detectadas com sintaxe C++. O Exemplo EXCEPTEX demonstra isso usando código dado acima.

Tipos de exceções do C++

Há várias categorias de exceções do C++ que podem ser detectadas por um programa com base do MFC:

  • Instâncias de classes derivadas do MFC CException
  • Instâncias de uma classe encapsulando um Win32 exceção
  • Instâncias _com_error uma classe que é gerado pelo Visual C++ 5.0 COM nativa oferece suporte disponível via a diretiva # import.
Para cada um deles, EXCEPTEX oferece uma função chamada LogException sobrecarregado para o tipo específico de exceção que está sendo detectada. Em cada caso, uma exceção dispara uma instância ou um ponteiro de um tipo específico, geralmente uma classe C++. Existem versões over-loaded do LogException para cada um dos tipos de exceção de C++ listados acima.

Abaixo é um exemplo da declaração para a função LogException sobrecarregada que captura um ponteiro para a classe do MFC CException.
    // Crack open and log details of different types of exceptions    extern void LogException( CException    *e,                              LPCSTR        lpszTimeStamp,                              LPCSTR        lpszFile,                              int           nLine        );				
LogException também controla o número de linha e o nome do arquivo onde a macro de exceção foi usada pela última vez na pilha de chamada (se usado com um auxiliar LOG macro).

Cada um desses auxiliar funciona rachaduras abrir a exceção e armazena os resultados em uma matriz de seqüência de caracteres que você pode processar conforme necessário. A função para despejar o conteúdo dessa matriz de seqüência de caracteres para a macro TRACE() é LogDisplay().

Simplificar try/catch blocos com macros do auxiliar

Littering blocos try/catch no seu código pode ficarem confusa após um tempo. No entanto, é possível simplificar blocos de exceção por meio do uso de macros. EXCEPTEX fornece três macros para simplificar esse processo, e cada um oferece diferentes funcionalidades para log/tratamento de exceções. Cada as macros também são gravados trabalham para 4.X Visual C++ e Visual C++ 5.0, e eles devem verificar a versão do compilador que você está usando.

Abaixo é a mais simples de macros, LOGQ (silencioso Exception Handling com nenhum log). Ele espera que uma variável Boolean denominada bRetVal está disponível no seu código. Devem ser verdadeira para que a macro pode permitir a execução do código que pode gerar uma exceção e ele define como FALSO se uma exceção é gerada.
    #if _MSC_VER < 1100    // For version VC++ 4.2 or earlier        #define LOGQ( f ) if( bRetVal == TRUE )                \                           {                                    \                              try                               \                              {                                 \                                  f;                            \                              }                                 \                              catch( CException *e )            \                              {                                 \                                 bRetVal = FALSE;               \                                  e->Delete();                  \                              }                                 \                              catch( SEH_Exception )            \                              {                                 \                                 bRetVal = FALSE;               \                              }                                 \                              catch(...)                        \                              {                                 \                                 bRetVal = FALSE;               \                              }                                 \                           }    #else        #define LOGQ( f ) if( bRetVal == TRUE )                \                           {                                    \                              try                               \                              {                                 \                                 f;                             \                              }                                 \                              catch( CException *e )            \                              {                                 \                                 bRetVal = FALSE;               \                                 e->Delete();                   \                              }                                 \                              catch( _com_error )               \                              {                                 \                                 bRetVal = FALSE;               \                               }                                \                              catch( SEH_Exception )            \                              {                                 \                                 bRetVal = FALSE;               \                              }                                 \                              catch(...)                        \                              {                                 \                                 bRetVal = FALSE;               \                              }                                 \                           }    #endif				
_MSC_VER # ifdef restringe a definição da macro a ser específico para Visual C++ 4.X ou 5.0. A versão 5.0 inclui um problema para a exceção _com_error recém-introduzidos (gerada pelo código criado a partir de # import).

Você usaria LOGQ conforme mostrado abaixo:
    int     i = 0;    int     j;    BOOL    bRetVal = TRUE;    // This code is not safe    j = 1 / i;        // Raises Win32 Divide By Zero exception    // This code is safe    LOGQ( j = 1 / i; )				
há duas versões das macros LOG fornecidas pelo EXCEPTEX. A segunda macro LOG usa os auxiliares LogException() sobrecarregados descritos acima.
    #define LOGE( f ) try                               \                       {                                 \                           f;                            \                       }                                 \                       catch( CException *e )            \                       {                                 \                           LogException( e,              \                                         __TIMESTAMP__,  \                                         __FILE__,       \                                         __LINE__      );\                       }                                 \                       ...				
esta macro faz uso de bRetVal sinalizador. Ele sempre será executar o código encapsulado pela macro, capturar quaisquer exceções geradas e faça seu conteúdo.

A macro LOG final fornecida pelo EXCEPTEX, LOGR, combina tanto LOGQ LOGE. Ele verifica se ele deve executar o código e efetuar qualquer exceção que é gerada.
    #define LOGR( f ) if( bRetVal == TRUE )                 \                       {                                     \                           try                               \                           {                                 \                               f;                            \                           }                                 \                           catch( CException *e )            \                           {                                 \                               LogException( e,              \                                             __TIMESTAMP__,  \                                             __FILE__,       \                                             __LINE__      );\                               bRetVal = FALSE;              \                           }                                 \                           ...                        }				

Outras funções úteis

O exemplo EXCEPTEX fornece três mais funções para ajudar a manipulação de exceção:
LogDisplay() Despeja o conteúdo de todas as exceções conectados fora via TRACE macros.

LogDisplay (...) Despeja o conteúdo de todas as exceções conectados saída a uma instância de CListBox.

LogSaveToFile (...) Despeja o conteúdo de todas as exceções fez check-out para um arquivo.

LOG.H e LOG.CPP

LOG.H e LOG.CPP conter todo o código em EXCEPTEX para manipular exceções. O restante do exemplo é demonstrar macros/funções encontradas em LOG.H e LOG.CPP. Esses dois arquivos podem ser facilmente adicionados a um projeto existente e foram escritos para compilar em qualquer 4.X Visual C++ ou cria 5.0 em ANSI e UNICODE. Usá-los, adicionar # incluir "log.h" para os arquivos que estará usando a macro LOGE ou LOGR. Se você deseja quebrar Win32 Structured exceções também, você deve chamar LogEnable uma vez próximo ao início do seu programa.
   // One time initialization of data    LogEnable(false);     // false to verbose mode				
adicionar a macro LOG no código que você deseja obter dados de exceção do.
   ...   LOGE(myFunction())   ...				
Observe que o arquivo e linha número relatado será a última macro LOG na pilha. Se myFunction() chama myFun1() e myFun2(), você precisará dispor cada chamada de função com uma macro LOG para a saída exibir a chamada a exceção ocorreu no.

Não é sempre aconselhável usar o LOG macros ou até mesmo os auxiliares LogException() conforme fornecido. Elas são oferecidas ambos como uma conveniência e como bem como para demonstrar o tratamento de exceções abrangente e para registrar os resultados de qualquer exceção detectada. Eles não são fornecidos como end-all, ser-tudo para manipulação de exceções em cada ambiente de produção.

Solução de problemas

O código a seguir mostra como para não usar as macros de auxiliar
    LOGQ( int i = 0; )    LOGQ( int j = 1 / i; )    // Will this raise a divide by zero?				
este código gerará um erro no compilador como i só é definido no escopo da primeira macro LOGQ. Lembre-se que LOGQ expande para:
>    ...    try    {        int i = 0;    }    ...    ...    try    {        int j = 1 / i;  // error C2065: 'i' : undeclared    }    ...				

/ W4 e # Import

Se você estiver usando o sinalizador/W4 no Visual C++ e # Import, você verá 8 avisos gerados desativar os arquivos de inclusão # Import utiliza.
comutil.h(905): aviso C4310: conversão trunca o valor constante
comutil.h(928): aviso C4310: conversão trunca o valor constante
comutil.h(1030): aviso C4310: conversão trunca o valor constante
comutil.h(1281): aviso C4310: conversão trunca o valor constante
comutil.h(1307): aviso C4310: conversão trunca o valor constante
comutil.h(1476): aviso C4310: conversão trunca o valor constante
comdef.h(242): aviso C4244: 'return': conversão de 'int' para 'unsigned o curto', possível perda de dados
Essas mensagens de erro podem ser ignoradas e não devem afetar o seu código.

Para obter mais informações

O seguinte tópico infoviewer VC ++ 5.0 apresentam uma boa introdução a técnicas de manipulação de exceção:
Manipulação de exceção: Perguntas freqüentes sobre
MK:@IVT:vccore/F26/D2A/S31BE4.HTM

Diferenças de manipulação de exceção
MK:@IVT:vccore/F26/D2B/S4CC99.HTM
O seguinte artigo demonstra técnicas que podem ser usadas para expandir o exemplo EXCEPTEX para manipular exceções do SDK do DAO.
152695Como catch e decifrar DAO SDK com exceções
Uma fonte definitiva na manipulação de exceção do Win32 pode ser encontrada em:

"Windows Avançado" por Jeffrey Richter, ISBN 1-57231-548-2

Aviso: este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 167802 - Última Revisão: 08/05/2004 20:02:50 - Revisão: 3.2

Microsoft Visual C++ 4.2 Enterprise Edition, Microsoft Visual C++ 5.0 Enterprise Edition, Microsoft Visual C++ 4.0 Standard Edition, Microsoft Visual C++ 4.1 Subscription, Microsoft Visual C++ 4.2 Professional Edition, Microsoft Visual C++ 5.0 Professional Edition

  • kbmt kbdownload kbdatabase kbfile kbsample KB167802 KbMtpt
Comentários