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

Traduções deste artigo Traduções deste artigo
ID do artigo: 167802 - Exibir os produtos aos quais esse artigo se aplica.
Expandir tudo | Recolher tudo

Neste artigo

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

Propriedades

ID do artigo: 167802 - Última revisão: quinta-feira, 5 de agosto de 2004 - Revisão: 3.2
A informação contida neste artigo aplica-se a:
  • 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
Palavras-chave: 
kbmt kbdownload kbdatabase kbfile kbsample KB167802 KbMtpt
Tradução automática
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.

Submeter comentários

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com