Traps EXCEPTEX MFC e Win32 estruturado de excepções

Traduções de Artigos Traduções de Artigos
Artigo: 167802 - Ver produtos para os quais este artigo se aplica.
Este artigo foi arquivado. Este artigo é oferecido "tal como está" e deixará de ser actualizado.
Expandir tudo | Reduzir tudo

Nesta página

Sumário

EXCEPTEX é um exemplo que demonstra técnicas de véu de excepções Structured Win32 e C++ excepções. Para o C++ excepções, ajuda várias funções são fornecidas que demonstram como violar abrir mais frequentemente utilizado classes de excepção. Excepções de Structured Win32, uma função do programa auxiliar é desde que identifica o tipo de excepção accionada em Win32.

Os ficheiros seguintes estão disponíveis para transferência a partir do Centro de transferências da Microsoft:


Exceptex.exe

Para obter informações adicionais sobre como transferir ficheiros de suporte da Microsoft, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
119591Como obter ficheiros de suporte da Microsoft a partir de serviços on-line
Microsoft procedeu de vírus neste ficheiro. Microsoft utilizou o mais recente software de detecção de vírus que estava disponível na data em que o ficheiro foi publicado. O ficheiro é alojado em servidores com segurança avançada que o ajudam a impedir alterações não autorizadas ao ficheiro.

Mais Informação

Intercalar Win32 e processamento de excepções de C++

Processamento de excepções de C++ e processamento Win32 Structured excepção utilizam sintaxe diferente para aplicar véus a excepçõ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 fundamental diferenças que processamento de excepções de C++ espera interceptar uma instância de um tipo, enquanto que o processamento Win32 Structured excepção identificou apenas três não assinados ints.

No entanto, pode intercalar C++ e excepção do Win32 processamento através da função _set_se_translator(). Isto provoca uma excepção de Win32 sejam transmitidas para a função de rotina de tratamento de sua escolha, que pode moldar informações de excepção de Win32 de uma classe e "accione-" como um C++ excepção. Isto acontece automaticamente quando ocorre uma excepção de Win32 e parece facilmente o programa como uma excepção de C++ (consulte a excepção de processamento diferenças em infoviewer VC 5.0). Este é feito por si automaticamente se utilizar as macros LOG e relacionados com suportam 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);

        ...
    }
				
neste caso, LogEnable iria ser chamado uma vez, numa fase inicial na execução do programa e quaisquer excepções de Win32 elevadas podem ser detectadas com sintaxe de C++. O EXCEPTEX exemplo demonstra esta utilizando o código especificado acima.

Tipos de excepções de C++

Existem várias categorias de excepções de C++ que podem ser detectadas por um programa MFC-com:

  • As instâncias das classes derivam do MFC CException
  • Instâncias de uma classe encapsulamento um Win32 excepção
  • Instâncias de uma classe _com_error que é aumentado pelo Visual C++ 5.0 nativo COM suporte disponível através da diretiva #import.
Para cada um deles, EXCEPTEX oferece uma função chamada LogException, sobrecarregado para o tipo específico de excepção que está a ser detectada. Em ambos os casos, uma excepção desencadeia uma instância ou um apontador de um tipo específico, normalmente, uma classe de C++. Existem versões over-loaded do LogException para cada um dos tipos de excepção de C++ listadas acima.

Segue-se um exemplo da declaração da função LogException sobrecarregado que identificou um ponteiro para a classe CException MFC.
    // Crack open and log details of different types of exceptions
    extern void LogException( CException    *e,
                              LPCSTR        lpszTimeStamp,
                              LPCSTR        lpszFile,
                              int           nLine        );
				
LogException controla também o número de linha e de nome de ficheiro onde a macro de excepção última foi utilizada na pilha de chamadas (se utilizado com um programa auxiliar reg macro).

Cada uma destes ajuda funciona fendas abrir a excepção e armazena os resultados numa matriz de cadeia que pode processar conforme necessário. A função para copiar o conteúdo desta matriz de cadeia para a macro TRACE() é LogDisplay().

Simplificar tente/catch bloqueia com macros do Gestor da impressão

Pode obter confusas littering blocos try/catch no código após algum tempo. No entanto, é possível simplificar blocos de excepção através da utilização de macros. EXCEPTEX fornece três macros para simplificar este processo e cada oferece funcionalidades diferentes para registo/tratamento de excepções. Todas as macros são também escritos são 4.X Visual C++ e Visual C++ 5.0, para que devem verificar a versão do compilador estiver a utilizar.

Segue-se mais simples das macros, LOGQ (silencioso excepção processamento com nenhum registo). Espera que uma variável booleana denominada bRetVal está disponível no código. Tem de ser verdadeira para que a macro pode permitir a execução do código que poderá originar uma excepção e define como FALSE se uma excepção é aumentada.
    #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 de Visual C++ 4.X ou 5.0. A versão 5.0 inclui um truque para a excepção _com_error recentemente introduzidos (gerada pelo código criado a partir de #import).

Utilizaria LOGQ conforme é ilustrado 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; )
				
existem duas outras versões das macros reg fornecidas pelo EXCEPTEX. A segunda macro reg utiliza os programas auxiliares LogException() sobrecarregados descritos acima.
    #define LOGE( f ) try                               \ 
                      {                                 \ 
                          f;                            \ 
                      }                                 \ 
                      catch( CException *e )            \ 
                      {                                 \ 
                          LogException( e,              \ 
                                        __TIMESTAMP__,  \ 
                                        __FILE__,       \ 
                                        __LINE__      );\ 
                      }                                 \ 
                      ...
				
não efectua esta macro utiliza bRetVal sinalizador. Será sempre executar código encapsulado pela macro, detectar quaisquer excepções elevadas e registar o respectivo conteúdo.

A macro reg final fornecida pelo EXCEPTEX, LOGR, combina tanto LOGQ LOGE. Verifica se deve executar o código e iniciar qualquer excepção é accionada.
    #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 funções mais para ajudar o processamento de excepções:
LogDisplay() Copia o conteúdo de todas as excepções registados fora através de macros TRACE.

LogDisplay (...) Copia o conteúdo de todas as excepções registados fora to an instance of CListBox.

LogSaveToFile (...) Copia o conteúdo de todas as excepções registados saída para um ficheiro.

LOG.H e LOG.CPP

LOG.H e LOG.CPP contêm todo o código de EXCEPTEX para lidar com excepções. O restante do exemplo está demonstrar as macros/funções do LOG.H e LOG.CPP. Estes dois ficheiros podem ser facilmente adicionados a um projecto existente e foram escritos para compilar no 4.X ou Visual C++ ou 5.0 em ANSI e UNICODE cria. Para utilizá-las, adicione # incluem "log.h" para os ficheiros que vão utilizar a macro LOGE ou LOGR. Se pretender violar também estruturado de excepções do Win32, tem de chamar LogEnable uma vez perto do início do programa.
   // One time initialization of data
    LogEnable(false);     // false to verbose mode
				
adicionar a macro reg no código que pretende obter dados de excepção de.
   ...
   LOGE(myFunction())
   ...
				
note que o número de ficheiro e a linha será a última macro reg na pilha. Se as chamadas myFunction() myFun1() e myFun2(), terá de moldar cada chamada de função com uma macro de registo para a saída mostrar qual ocorreu a excepção da chamada.

Convém não sempre que utilizar o registo macros ou mesmo os helpers LogException() conforme fornecido. São oferecidas ambos como uma comodidade e como bem como para demonstrar o processamento de excepções abrangente e para registar os resultados de qualquer excepção detectada. São fornecidas como end-all, ser-tudo para processamento de excepções no cada ambiente de produção.

Resolução de problemas

O seguinte código mostra como para não utilizar as macros de programa auxiliar
    LOGQ( int i = 0; )
    LOGQ( int j = 1 / i; )    // Will this raise a divide by zero?
				
este código gera um erro de compilador como i apenas é definido no âmbito 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 estiver a utilizar o sinalizador /W4 no Visual C++ e #import, verá 8 avisos gerados desactivar os ficheiros 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' 'não assinado curto', é possível perda de dados
Estas mensagens de erro podem ser ignoradas e não deverão afectar o código.

Para mais informações

O seguinte tópico de infoviewer VC ++ 5.0 apresentar uma boa introdução a técnicas de processamento de excepções:
Processamento de excepções: Perguntas mais frequentes
mk:@IVT:vccore/F26/D2A/S31BE4.HTM

Diferenças de processamento de excepções
mk:@IVT:vccore/F26/D2B/S4CC99.HTM
O seguinte artigo demonstra técnicas que podem ser utilizadas para expandir o exemplo EXCEPTEX para processar DAO SDK excepções.
152695Como Apanha e decifrar DAO SDK com excepções
Uma origem definitiva de processamento de excepções do Win32 pode ser encontrada em:

"Windows avançadas" por Jeffrey Richter, ISBN 1-57231-548-2

Propriedades

Artigo: 167802 - Última revisão: 10 de fevereiro de 2014 - 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: 
kbnosurvey kbarchive 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 revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 167802

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