Partager via


Gestion et notification des erreurs

Si votre programme utilise des DLL chargées en retard, il doit gérer les erreurs de manière robuste, car les échecs qui se produisent pendant l’exécution du programme entraînent des exceptions non gérées. La gestion des défaillances se compose de deux parties : la récupération via un hook et la création de rapports via une exception.

Pour plus d’informations sur la gestion et la notification des erreurs de chargement des retards dll, consultez Comprendre la fonction d’assistance.

Pour plus d’informations sur les fonctions de raccordement, consultez Les définitions de structure et de constante.

Récupération par le biais d’un hook

Votre code peut avoir besoin de récupérer en cas d’échec, ou de fournir une autre bibliothèque ou routine. Vous pouvez fournir un hook à la fonction d’assistance qui peut fournir le code de remplacement ou remédier à la situation. La routine de raccordement doit retourner une valeur appropriée, afin que le traitement puisse continuer (une HINSTANCE ou FARPROC). Il peut également retourner 0 pour indiquer qu’une exception doit être levée. Il peut également lever sa propre exception ou longjmp hors du crochet. Il existe des hooks de notification et des crochets d’échec. La même routine peut être utilisée pour les deux.

Raccordements de notification

Les hooks de notification de chargement de retard sont appelés juste avant que les actions suivantes soient effectuées dans la routine d’assistance :

  • Le handle stocké dans la bibliothèque est case activée pour voir s’il a déjà été chargé.

  • LoadLibrary est appelé pour tenter la charge de la DLL.

  • GetProcAddress est appelé pour tenter d’obtenir l’adresse de la procédure.

  • Revenez au bloc de chargement de l’importation différée.

Le hook de notification est activé :

  • En fournissant une nouvelle définition du pointeur __pfnDliNotifyHook2 initialisé pour pointer vers votre propre fonction qui reçoit les notifications.

    -ou-

  • En définissant le pointeur __pfnDliNotifyHook2 vers votre fonction de hook avant tout appel à la DLL que le programme retarde le chargement.

Si la notification est dliStartProcessing, la fonction de hook peut retourner :

  • NULL

    L’assistance par défaut gère le chargement de la DLL. Il est utile d’appeler uniquement à des fins d’information.

  • pointeur de fonction

    Ignorez la gestion par défaut du délai de chargement. Il vous permet de fournir votre propre gestionnaire de charge.

Si la notification est dliNotePreLoadLibrary, la fonction de hook peut retourner :

  • 0, s’il veut simplement des notifications d’information.

  • Pour HMODULE la DLL chargée, si elle a chargé la DLL elle-même.

Si la notification est dliNotePreGetProcAddress, la fonction de hook peut retourner :

  • 0, s’il veut simplement des notifications d’information.

  • Adresse de la fonction importée, si la fonction de hook obtient l’adresse elle-même.

Si la notification est dliNoteEndProcessing, la valeur de retour de la fonction de hook est ignorée.

Si ce pointeur est initialisé (différent de zéro), l’assistance de chargement différé appelle la fonction à certains points de notification tout au long de son exécution. Le pointeur de fonction a la définition suivante :

// The "notify hook" gets called for every call to the
// delay load helper.  This allows a user to hook every call and
// skip the delay load helper entirely.
//
// dliNotify == {
//  dliStartProcessing |
//  dliNotePreLoadLibrary  |
//  dliNotePreGetProc |
//  dliNoteEndProcessing}
//  on this call.
//
ExternC
PfnDliHook   __pfnDliNotifyHook2;

// This is the failure hook, dliNotify = {dliFailLoadLib|dliFailGetProc}
ExternC
PfnDliHook   __pfnDliFailureHook2;

Les notifications passent une DelayLoadInfo structure à la fonction de hook, ainsi que la valeur de notification. Ces données sont identiques aux données utilisées par la routine d’assistance de chargement différée. La valeur de notification est l’une des valeurs définies dans les définitions de structure et de constante.

Raccordements de défaillance

Le hook d’échec est activé de la même manière que le hook de notification. La routine de raccordement doit retourner une valeur appropriée afin que le traitement puisse continuer (ou HINSTANCE ) ou FARPROC0 pour indiquer qu’une exception doit être levée.

La variable de pointeur qui fait référence à la fonction définie par l’utilisateur est la suivante :

// This is the failure hook, dliNotify = {dliFailLoadLib|dliFailGetProc}
ExternC
PfnDliHook   __pfnDliFailureHook2;

La DelayLoadInfo structure contient toutes les données pertinentes nécessaires pour la création de rapports détaillés de l’erreur, y compris la valeur de GetLastError.

Si la notification est dliFailLoadLib, la fonction de hook peut retourner :

  • 0, s’il ne peut pas gérer l’échec.

  • Si HMODULEle hook d’échec a résolu le problème et chargé la bibliothèque elle-même.

Si la notification est dliFailGetProc, la fonction de hook peut retourner :

  • 0, s’il ne peut pas gérer l’échec.

  • Adresse de procédure valide (adresse de fonction d’importation), si le hook d’échec a réussi à obtenir l’adresse elle-même.

Signaler à l’aide d’une exception

Si tout ce qui est nécessaire pour gérer l’erreur consiste à abandonner la procédure, aucun hook n’est nécessaire, tant que le code utilisateur peut gérer l’exception.

Retarder les codes d’exception de chargement

Les codes d’exception structurés peuvent être déclenchés lorsque des défaillances se produisent pendant une charge retardée. Les valeurs d’exception sont spécifiées à l’aide d’une VcppException macro :

//
// Exception information
//
#define FACILITY_VISUALCPP  ((LONG)0x6d)
#define VcppException(sev,err)  ((sev) | (FACILITY_VISUALCPP<<16) | err)

Pour une LoadLibrary défaillance, la norme VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND) est levée. Pour un GetProcAddress échec, l’erreur levée est VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND). L’exception transmet un pointeur à une DelayLoadInfo structure. Elle se trouve dans la LPDWORD valeur récupérée à GetExceptionInformation partir de la EXCEPTION_RECORD structure, dans le ExceptionInformation[0] champ.

Si les bits incorrects sont définis dans le grAttrs champ, l’exception ERROR_INVALID_PARAMETER est levée. Cette exception est, à toutes fins et intentions, irrécupérable.

Pour plus d’informations, consultez Les définitions de structure et de constante.

Voir aussi

Prise en charge de l’éditeur de liens pour les DLL chargées en retard