Capturas EXCEPTEX Win32 de MFC y estructurado de excepciones

Seleccione idioma Seleccione idioma
Id. de artículo: 167802 - Ver los productos a los que se aplica este artículo
Este artículo se ha archivado. Se ofrece "tal cual" y no se volverá a actualizar.
Expandir todo | Contraer todo

En esta página

Resumen

EXCEPTEX es un ejemplo que muestra técnicas para la captura de excepciones estructurado de Win32 y excepciones de C++. Para C++ excepciones, diversos auxiliar se proporcionan funciones que muestran cómo averiguar el más abierto utilizan clases de excepción. De excepciones estructurado de Win32, una función auxiliar es siempre identifica el tipo de excepción de Win32.

Los archivos siguientes están disponibles para descargarlos del Centro de descarga de Microsoft:


Exceptex.exe

Para obtener información adicional acerca de cómo descargar los archivos de soporte técnico de Microsoft, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
119591Cómo obtener Archivos de soporte técnico de Microsoft desde los servicios en línea
Microsoft exploró este archivo en busca de virus. con el software de detección de virus más reciente disponible en la fecha de publicación. Asimismo, el archivo se almacenó en servidores seguros que ayudan a impedir la realización de cambios no autorizados.

Más información

Combinación de Win32 y excepciones de C++

Control de excepciones de C++ y Win32 Structured Exception Handling utilizar una sintaxis diferente para interceptar excepciones.
    // 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
    }
				
diferencia el concepto básico que espera control de excepciones de C++ detectar una instancia de un tipo, mientras que Win32 control estructurado de excepciones detecta sólo tres unsigned ints.

Puede, sin embargo, combinar C++ y controlar mediante la función _set_se_translator() de excepción de Win32. Esto provoca una excepción Win32 pasen a la función de controlador de su elección, que puede ajustar la información de excepción de Win32 en una clase y "throw" como un C++ excepción. Esto sucede automáticamente cuando se produce una excepción de Win32 y aparece perfectamente al programa como una excepción de C++ (vea diferencias de control de excepciones en el VC 5.0 infoviewer). Se trata de realizará automáticamente si utiliza las macros LOG y relacionados con admite funciones 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);

        ...
    }
				
en este caso, LogEnable llamaría una vez, pronto en la ejecución del programa y las excepciones de Win32 provocadas podrían capturarse con sintaxis de C++. El EXCEPTEX ilustra esto mediante el código anterior.

Tipos de excepciones de C++

Hay varias categorías de excepciones de C++ que pueden detectar un programa basados en MFC:

  • Instancias de clases derivan de MFC CException
  • Las instancias de una clase que encapsula un Win32 excepciones
  • Las instancias de un _com_error de clase que se desencadena por Visual C++ 5.0 COM nativo admite disponible a través de la directiva # import.
Para cada una de ellas EXCEPTEX ofrece una función denominada LogException, sobrecargado para el tipo de excepción detectada se específico. En cada caso una excepción provoca una instancia o un puntero de un tipo específico, normalmente una clase de C++. Hay versiones over-loaded de LogException para cada uno de los tipos de excepciones de C++ enumerados anteriormente.

A continuación es un ejemplo de la declaración de la función sobrecargada LogException que detecta un puntero a la clase CException de MFC.
    // Crack open and log details of different types of exceptions
    extern void LogException( CException    *e,
                              LPCSTR        lpszTimeStamp,
                              LPCSTR        lpszFile,
                              int           nLine        );
				
LogException controla también el número de nombre y la línea del archivo donde la macro de excepción por última vez se utilizó en la pila de llamadas (si utiliza con un Ayudante LOG macro).

Cada uno de estos auxiliar funciones grietas abrir la excepción y almacena los resultados en una matriz de cadena que puede procesar como sea necesario. La función para volcar el contenido de esta matriz de cadena a la macro TRACE() es LogDisplay().

Simplificación de try/catch bloques con macros de Ayuda

Inundar bloques try/catch en el código puede obtener desordenada después de un rato. Sin embargo, es posible simplificar bloques de excepción a través del uso de macros. EXCEPTEX proporciona tres macros para simplificar este proceso, y cada uno ofrece funcionalidad diferente para el registro y control de excepciones. Cada una de las macros se escriben también en funcionan para C++ 4.X y para Visual C++ 5.0, por lo que debe comprobar la versión del compilador que utiliza.

A continuación es la más sencilla de las macros LOGQ (silencioso control de excepciones con ningún registro). Espera que una variable booleana llamada bRetVal está disponible en el código. Debe ser true para que la macro puede permitir la ejecución del código que puede provocar una excepción y se establece en FALSE si se produce una excepción.
    #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
				
el _MSC_VER # ifdef restringe la definición de la macro para ser específicas de Visual C++ 4.X ó 5.0. La versión 5.0 incluye un problema de la excepción _com_error recién introducidos (generado por código creado a partir de # import).

Utilice LOGQ tal como se muestra a continuación:
    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; )
				
hay otras dos versiones de las macros LOG proporcionadas EXCEPTEX. La segunda macro LOG utiliza los ayudantes LogException() sobrecargados que se ha descrito anteriormente.
    #define LOGE( f ) try                               \ 
                      {                                 \ 
                          f;                            \ 
                      }                                 \ 
                      catch( CException *e )            \ 
                      {                                 \ 
                          LogException( e,              \ 
                                        __TIMESTAMP__,  \ 
                                        __FILE__,       \ 
                                        __LINE__      );\ 
                      }                                 \ 
                      ...
				
no hace que esta macro utiliza el indicador bRetVal. Siempre se ejecutar el código encapsulado por la macro, detectar las excepciones que produce y registrar su contenido.

La macro LOG final proporcionada por EXCEPTEX, LOGR, combina LOGQ y LOGE. Se comprueba si debe ejecutar el código y registrar cualquier excepción que se provoca.
    #define LOGR( f ) if( bRetVal == TRUE )                 \ 
                      {                                     \ 
                          try                               \ 
                          {                                 \ 
                              f;                            \ 
                          }                                 \ 
                          catch( CException *e )            \ 
                          {                                 \ 
                              LogException( e,              \ 
                                            __TIMESTAMP__,  \ 
                                            __FILE__,       \ 
                                            __LINE__      );\ 
                              bRetVal = FALSE;              \ 
                          }                                 \ 
                          ...
                        }
				

Otras funciones útiles

El ejemplo EXCEPTEX proporciona tres más funciones para ayudar a control de excepciones:
LogDisplay() Vuelca el contenido de todas las excepciones registradas fuera a través de las macros TRACE.

LogDisplay (...) Vuelca el contenido de todas las excepciones ha iniciado sesión a una instancia de CListBox.

LogSaveToFile (...) Vuelca el contenido de todas las excepciones registradas fuera de un archivo.

LOG.H y LOG.CPP

LOG.H y LOG.CPP contienen todos el código de EXCEPTEX para controlar las excepciones. El resto del ejemplo es demostrar las macros y funciones encontradas en LOG.H y LOG.CPP. Estos dos archivos se pueden agregar fácilmente a un proyecto existente y se escribieron en compilar en ambos 4.X de C++ o genera 5.0 en ANSI y UNICODE. Para usarlos, agregue # include "log.h" para los archivos que va a utilizar la macro LOGE o LOGR. Si desea descifrar también de excepciones estructurado de Win32, debe llamar a LogEnable una vez cerca del principio del programa.
   // One time initialization of data
    LogEnable(false);     // false to verbose mode
				
agregar la macro LOG en el código que desea obtener datos de excepción de.
   ...
   LOGE(myFunction())
   ...
				
nota que indica el archivo y el número de línea será la última macro LOG en la pila. Si se llama a myFunction() myFun1() y myFun2(), tendrá que ajustar cada llamada de función con una macro LOG para la salida mostrar donde se produjo la excepción en la llamada.

Puede que no siempre desee utilizar el LOG macros o incluso los ayudantes LogException() como lo proporciona. Éstas se ofrecen dos comodidad y como así como para mostrar el control de excepciones completa y para registrar los resultados de cualquier excepción detectada. No se proporcionan como el end-all ser todo control de excepciones en cada entorno de producción.

Solución de problemas

El código siguiente muestra cómo utilizar las macros auxiliar
    LOGQ( int i = 0; )
    LOGQ( int j = 1 / i; )    // Will this raise a divide by zero?
				
este código genera un error del compilador como i sólo está definido en el ámbito de la primera macro LOGQ. Recuerde que LOGQ se expande para:
>
    ...
    try
    {
        int i = 0;
    }
    ...

    ...
    try
    {
        int j = 1 / i;  // error C2065: 'i' : undeclared
    }
    ...
				

/ W4 y # Import

Si está utilizando el indicador/W4 en Visual C++ y # Import, verá 8 advertencias generadas los archivos de inclusión utiliza # import.
comutil.h(905): advertencia C4310: conversión trunca el valor constante
comutil.h(928): advertencia C4310: conversión trunca el valor constante
comutil.h(1030): advertencia C4310: conversión trunca el valor constante
comutil.h(1281): advertencia C4310: conversión trunca el valor constante
comutil.h(1307): advertencia C4310: conversión trunca el valor constante
comutil.h(1476): advertencia C4310: conversión trunca el valor constante
comdef.h(242): advertencia C4244: 'return': conversión de 'int' a 'corta sin signo', posible pérdida de datos
Estos mensajes de error pueden pasarse por alto y no deben afectar al código.

Para obtener más información

El siguiente tema infoviewer de VC ++ 5.0 presentan una buena introducción al control técnicas de excepciones:
Control de excepciones: Preguntas más frecuentes
mk:@IVT:vccore/F26/D2A/S31BE4.HTM

Diferencias de control de excepciones
mk:@IVT:vccore/F26/D2B/S4CC99.HTM
El artículo siguiente muestra técnicas que podrían utilizarse para ampliar el ejemplo EXCEPTEX para controlar las excepciones del SDK de DAO.
152695Cómo catch y descifrar excepciones de SDK de DAO
Un origen conocido en control de excepciones de Win32 se puede encontrar en:

"Windows avanzadas" por Jeffrey Richter, ISBN 1-57231-548-2

Propiedades

Id. de artículo: 167802 - Última revisión: lunes, 3 de febrero de 2014 - Versión: 3.2
La información de este artículo se refiere 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
Palabras clave: 
kbnosurvey kbarchive kbmt kbdownload kbdatabase kbfile kbsample KB167802 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 167802

Enviar comentarios

 

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