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 vérifié 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 FARPROC
0 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
HMODULE
le 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