Interruptions EXCEPTEX MFC et Win32 structurée des exceptions

Traductions disponibles Traductions disponibles
Numéro d'article: 167802 - Voir les produits auxquels s'applique cet article
Cet article a été archivé. Il est proposé « en l'état » et ne sera plus mis à jour.
Agrandir tout | Réduire tout

Sommaire

Résumé

EXCEPTEX est un exemple qui montre des techniques de piégeage des exceptions structuré Win32 et des C++ Exceptions. Pour C++ exceptions, divers helper fonctions sont fournies qui montrent comment fissure ouverte plus couramment utilisées classes d'exception. Pour les exceptions structurées Win32, une fonction d'assistance est fourni qui identifie le type d'exception Win32.

Les fichiers suivants sont disponibles au téléchargement à partir du centre de téléchargement Microsoft :


Exceptex.exe

Pour plus d'informations sur la façon de télécharger des fichiers de support technique Microsoft, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la base de connaissances Microsoft :
119591Procédure pour obtenir des fichiers de support technique Microsoft auprès des services en ligne
Microsoft a analysé ce fichier pour les virus. Microsoft utilisé les logiciels de détection de virus les plus récentes ne sont associé à la date à laquelle le fichier a été validé. Le fichier est stocké sur des serveurs sécurisés, empêchant toute modification non autorisée du fichier.

Plus d'informations

Fusion de Win32 et de gestion des exceptions C++

Gestion de le C++ Exception et Win32 Structured Exception Handling utiliser syntaxe différente pour intercepter les exceptions.
    // 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
    }
				
Fondamentales différence étant que gestion des exceptions C++ s'attend à intercepter une instance d'un type, alors que Win32 Structured Exception Handling intercepte uniquement trois unsigned int.

Vous pouvez, toutefois, fusionner C++ et Exception Win32 expédition via la fonction _set_se_translator(). Cela provoque une exception Win32 à transmettre à la fonction de gestionnaire de votre choix, qui peut intégrer des informations de Win32 Exception dans une classe et «throw"comme un C++ exception. Cela produit automatiquement lorsqu'une Exception Win32 est survenue et apparaît en toute transparence au programme sous la forme d'une exception C++ (consultez Exception Handling différences dans l'infoviewer VC 5.0). Il s'agit effectuée automatiquement si vous utilisez les macros LOG et lié prend en charge les fonctions 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);

        ...
    }
				
Dans ce cas, LogEnable devrait être appelé une seule fois, au début dans l'exécution du programme et les exceptions Win32 levées pourraient être interceptées avec la syntaxe C++. L'Il EXCEPTEX illustre cela à l'aide du code ci-dessus.

Types d'exceptions C++

Il existe différentes catégories d'exceptions C++ qui peuvent être interceptées par un programme MFC :

  • Instances de classes dérivées de MFC CException
  • Instances d'une classe encapsulant un Win32 Exception
  • Instances d'un _com_error de classe qui est évoquée par Visual C++ 5.0 COM natif prend en charge disponible via la directive # import.
Pour chacun d'entre eux, EXCEPTEX offre une fonction appelée LogException surchargée pour le type spécifique d'exception qui est détectée. Dans chaque cas, une exception déclenche une instance ou un pointeur d'un type spécifique, généralement une classe C++. Il existe des versions over-loaded de LogException pour chacun des types d'exception C++ répertoriés ci-dessus.

Voici un exemple de la déclaration de la fonction LogException surchargée qui intercepte un pointeur vers la classe MFC CException.
    // Crack open and log details of different types of exceptions
    extern void LogException( CException    *e,
                              LPCSTR        lpszTimeStamp,
                              LPCSTR        lpszFile,
                              int           nLine        );
				
LogException suit également le nombre de nom et la ligne de fichier où la macro exception dernière utilisation de la pile des appels (si utilisé avec une application d'assistance LOG macro).

Chacun de ces d'assistance fonctionne fissures ouvert l'exception et stocke les résultats dans un tableau de chaînes que vous pouvez traiter que nécessaire. La fonction pour vider le contenu de ce tableau de chaînes à la macro TRACE() est LogDisplay().

Simplification try/catch bloque de nouveau les macros d'assistance

Alourdir les blocs try/catch dans votre code peut obtenir désordonné après un certain temps. Toutefois, il est possible de simplifier les blocs d'exception à l'aide de macros. EXCEPTEX fournit trois macros pour simplifier ce processus et chacun offre des fonctionnalités différentes pour la journalisation/gestion des exceptions. Chacune des macros sont également écrits dans fonctionne pour Visual C++ 4.X et 5.0 de Visual C++, afin qu'ils doivent vérifier la version de compilateur que vous utilisez.

Vous trouverez ci-dessous la plus simple des macros, LOGQ (gestion silencieux des exceptions sans consignation des commentaires). Il attend qu'une variable Boolean nommée bRetVal est disponible dans votre code. Il doit être true pour que la macro peut permettre l'exécution du code peut lever une exception, et il lui attribue la valeur False si une exception est levée.
    #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
				
Le _MSC_VER # ifdef restreint la définition de la macro à être spécifiques à Visual C++ 4.X ou 5.0. La version 5.0 inclut un bloc catch pour l'exception _com_error nouvellement introduites (généré par le code créé à partir de # import).

Vous devez utiliser LOGQ comme suit :
    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; )
				
il existe deux autres versions de macros LOG fournies par EXCEPTEX. La deuxième macro LOG utilise les applications d'assistance LogException() surchargées décrites ci-dessus.
    #define LOGE( f ) try                               \ 
                      {                                 \ 
                          f;                            \ 
                      }                                 \ 
                      catch( CException *e )            \ 
                      {                                 \ 
                          LogException( e,              \ 
                                        __TIMESTAMP__,  \ 
                                        __FILE__,       \ 
                                        __LINE__      );\ 
                      }                                 \ 
                      ...
				
Cette macro ne fait pas utiliser de l'indicateur bRetVal. Il sera toujours exécuter le code encapsulé par la macro, intercepter les exceptions levées et consigner leur contenu.

La macro LOG finale fournie par EXCEPTEX, LOGR, combine les LOGQ et LOGE. Il vérifie si elle doit exécuter le code et enregistrer toute exception qui est déclenchée.
    #define LOGR( f ) if( bRetVal == TRUE )                 \ 
                      {                                     \ 
                          try                               \ 
                          {                                 \ 
                              f;                            \ 
                          }                                 \ 
                          catch( CException *e )            \ 
                          {                                 \ 
                              LogException( e,              \ 
                                            __TIMESTAMP__,  \ 
                                            __FILE__,       \ 
                                            __LINE__      );\ 
                              bRetVal = FALSE;              \ 
                          }                                 \ 
                          ...
                        }
				

Autres fonctions utiles

L'exemple EXCEPTEX fournit trois fonctions plus pour faciliter la gestion des exceptions :
LogDisplay() Vide le contenu de toutes les exceptions connectées hors via les macros TRACE.

LogDisplay (...) Vide le contenu de toutes les exceptions hors connectées à une instance de CListBox.

LogSaveToFile (...) Vide le contenu de toutes les exceptions connectées hors dans un fichier.

LOG.H et LOG.CPP

LOG.H et LOG.CPP contiennent tout le code dans EXCEPTEX pour gérer les exceptions. Le reste de l'échantillon est de montrer des macros/fonctions LOG.H et LOG.CPP. Ces deux fichiers peuvent être facilement ajoutés à un projet existant et ont été écrites à compiler dans soit Visual C++ 4.X ou 5.0 sous ANSI et UNICODE s'appuie. Pour les utiliser, ajoutez # include «log.h» pour les fichiers qui utiliseront la macro LOGE ou LOGR. Si vous souhaitez craquer également des exceptions structuré Win32, vous devez appeler une fois LogEnable vers le début de votre programme.
   // One time initialization of data
    LogEnable(false);     // false to verbose mode
				
Ajouter la macro LOG dans le code pour obtenir des données d'exception à partir de.
   ...
   LOGE(myFunction())
   ...
				
Remarque que le fichier et le numéro de ligne signalé sera la dernière macro LOG dans la pile. Si myFunction() appelle myFun1() et myFun2(), vous devez envelopper chaque appel de fonction avec une macro LOG pour la sortie afficher l'appel à l'exception s'est produite dans.

Vous pouvez toujours souhaitez pas utiliser le LOG macros ou même l'assistance LogException() tel que prévu. Ils sont proposés à la fois à titre de commodité et aussi bien à faire apparaître la gestion des exceptions complète et pour la consignation des résultats de n'importe quelle exception interceptée. Ils ne sont pas fournies en tant que l'end-all, être-all pour la gestion des exceptions dans chaque environnement de production.

Résolution des problèmes

Le code suivant montre comment ne pas utiliser les macros d'assistance
    LOGQ( int i = 0; )
    LOGQ( int j = 1 / i; )    // Will this raise a divide by zero?
				
ce code génère une erreur du compilateur tel qu'i est défini uniquement dans la portée de la première macro LOGQ. N'oubliez pas que LOGQ se développe pour :
>
    ...
    try
    {
        int i = 0;
    }
    ...

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

/ W4 et # import

Si vous utilisez l'indicateur/W4 dans Visual C++ et # import, vous verrez 8 avertissements générés sur les fichiers include qui utilise # import.
comutil.h(905) : avertissement C4310 : cast tronque la valeur de constante
comutil.h(928) : avertissement C4310 : cast tronque la valeur de constante
comutil.h(1030) : avertissement C4310 : cast tronque la valeur de constante
comutil.h(1281) : avertissement C4310 : cast tronque la valeur de constante
comutil.h(1307) : avertissement C4310 : cast tronque la valeur de constante
comutil.h(1476) : avertissement C4310 : cast tronque la valeur de constante
comdef.h(242) : avertissement C4244: 'return': conversion de 'int' en «non signé court», possible perte de données
Ces messages d'erreur peuvent être ignorés et ne doivent pas affecter votre code.

Pour plus d'informations.

La rubrique infoviewer VC ++ 5.0 suivante présente une bonne introduction aux techniques de gestion des exceptions :
Gestion des exceptions : Questions fréquemment posées sur
mk:@ivt:vccore/F26/D2A/S31BE4.HTM

Différences de gestion des exceptions
mk:@ivt:vccore/F26/D2B/S4CC99.HTM
L'article suivant explique les techniques qui pourraient être utilisées pour développer l'exemple EXCEPTEX pour gérer les exceptions DAO SDK.
152695Comment catch et déchiffrer les exceptions de Kit de développement logiciel DAO
Vous trouverez une source définitive sur Win32 Exception Handling dans :

"Windows avancées" par Jeffrey Richter, ISBN 1-57231-548-2

Propriétés

Numéro d'article: 167802 - Dernière mise à jour: dimanche 9 février 2014 - Version: 3.2
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft Visual C++ 4.2 Édition Entreprise
  • Microsoft Visual C++ 5.0 Édition Entreprise
  • Microsoft Visual C++ 4.0 Édition Standard
  • Microsoft Visual C++ 4.1 Subscription
  • Microsoft Visual C++ 4.2 Édition Professionnelle
  • Microsoft Visual C++ 5.0 Édition Professionnelle
Mots-clés : 
kbnosurvey kbarchive kbmt kbdownload kbdatabase kbfile kbsample KB167802 KbMtfr
Traduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 167802
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

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