Você está offline; aguardando reconexão

Traps EXCEPTEX MFC e Win32 estruturado de excepçõ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 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
Este artigo foi arquivado. Este artigo é oferecido "tal como está" e deixará de ser actualizado.
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

Aviso: Este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 167802 - Última Revisão: 02/10/2014 01:36:28 - 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

  • kbnosurvey kbarchive kbmt kbdownload kbdatabase kbfile kbsample KB167802 KbMtpt
Comentários