Gestione e notifica degli errori
Se il programma usa DLL caricate in ritardo, deve gestire gli errori in modo affidabile, poiché gli errori che si verificano durante l'esecuzione del programma genereranno eccezioni non gestite. La gestione degli errori è costituita da due parti: ripristino tramite un hook e segnalazione tramite un'eccezione.
Per altre informazioni sulla gestione e la notifica degli errori di caricamento ritardato della DLL, vedere Informazioni sulla funzione helper.
Per altre informazioni sulle funzioni hook, vedere Struttura e definizioni costanti.
Ripristino tramite un hook
Il codice potrebbe dover eseguire il ripristino in caso di errore o per fornire una libreria o una routine alternativa. È possibile fornire un hook alla funzione helper che può fornire il codice alternativo o risolvere la situazione. La routine hook deve restituire un valore appropriato, in modo che l'elaborazione possa continuare (o HINSTANCE
FARPROC
). In alternativa, può restituire 0 per indicare che deve essere generata un'eccezione. Potrebbe anche generare la propria eccezione o longjmp
uscire dall'hook. Sono disponibili hook di notifica e hook di errore. La stessa routine può essere utilizzata per entrambi.
Hook di notifica
Gli hook di notifica di caricamento ritardato vengono chiamati subito prima che vengano eseguite le azioni seguenti nella routine helper:
L'handle archiviato nella libreria viene controllato per verificare se è già stato caricato.
LoadLibrary
viene chiamato per tentare il caricamento della DLL.GetProcAddress
viene chiamato per tentare di ottenere l'indirizzo della routine.Tornare al caricamento di caricamento ritardato del caricamento.
L'hook di notifica è abilitato:
Specificando una nuova definizione del puntatore
__pfnDliNotifyHook2
inizializzato per puntare alla propria funzione che riceve le notifiche.oppure
Impostando il puntatore
__pfnDliNotifyHook2
sulla funzione hook prima di qualsiasi chiamata alla DLL che il programma ritarda il caricamento.
Se la notifica è dliStartProcessing
, la funzione hook può restituire:
NULL
L'helper predefinito gestisce il caricamento della DLL. È utile chiamare solo a scopo informativo.
puntatore a funzione
Ignorare la gestione predefinita del caricamento ritardato. Consente di fornire un gestore di carico personalizzato.
Se la notifica è dliNotePreLoadLibrary
, la funzione hook può restituire:
0, se vuole solo notifiche informative.
Oggetto
HMODULE
per la DLL caricata, se ha caricato la DLL stessa.
Se la notifica è dliNotePreGetProcAddress
, la funzione hook può restituire:
0, se vuole solo notifiche informative.
Indirizzo della funzione importata, se la funzione hook ottiene l'indirizzo stesso.
Se la notifica è dliNoteEndProcessing
, il valore restituito della funzione hook viene ignorato.
Se questo puntatore viene inizializzato (diverso da zero), l'helper di caricamento ritardato richiama la funzione in determinati punti di notifica durante l'esecuzione. Il puntatore di funzione ha la definizione seguente:
// 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;
Le notifiche passano una DelayLoadInfo
struttura alla funzione hook insieme al valore di notifica. Questi dati sono identici ai dati usati dalla routine helper di caricamento ritardato. Il valore di notifica sarà uno dei valori definiti in Struttura e definizioni costanti.
Hook di errore
L'hook di errore è abilitato nello stesso modo dell'hook di notifica. La routine hook deve restituire un valore appropriato in modo che l'elaborazione possa continuare (o HINSTANCE
FARPROC
) o 0 per indicare che deve essere generata un'eccezione.
La variabile puntatore che fa riferimento alla funzione definita dall'utente è:
// This is the failure hook, dliNotify = {dliFailLoadLib|dliFailGetProc}
ExternC
PfnDliHook __pfnDliFailureHook2;
La DelayLoadInfo
struttura contiene tutti i dati pertinenti necessari per la segnalazione dettagliata dell'errore, incluso il valore di GetLastError
.
Se la notifica è dliFailLoadLib
, la funzione hook può restituire:
0, se non riesce a gestire l'errore.
Oggetto
HMODULE
, se l'hook di errore ha risolto il problema e caricato la libreria stessa.
Se la notifica è dliFailGetProc
, la funzione hook può restituire:
0, se non riesce a gestire l'errore.
Indirizzo di processo valido (indirizzo della funzione di importazione), se l'hook di errore ha avuto esito positivo nel recupero dell'indirizzo stesso.
Creare report usando un'eccezione
Se tutto ciò che è necessario per gestire l'errore consiste nell'interrompere la procedura, non è necessario alcun hook, purché il codice utente possa gestire l'eccezione.
Codici eccezione di caricamento ritardato
I codici di eccezione strutturati possono essere generati quando si verificano errori durante un caricamento ritardato. I valori delle eccezioni vengono specificati utilizzando una VcppException
macro:
//
// Exception information
//
#define FACILITY_VISUALCPP ((LONG)0x6d)
#define VcppException(sev,err) ((sev) | (FACILITY_VISUALCPP<<16) | err)
Per un LoadLibrary
errore, viene generato lo standard VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND)
. Per un GetProcAddress
errore, l'errore generato è VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND)
. L'eccezione passa un puntatore a una DelayLoadInfo
struttura. Si trova nel LPDWORD
valore recuperato dalla GetExceptionInformation
EXCEPTION_RECORD
struttura, nel ExceptionInformation[0]
campo .
Se nel campo vengono impostati grAttrs
bit non corretti, viene generata l'eccezione ERROR_INVALID_PARAMETER
. Questa eccezione è, per tutte le finalità e gli scopi, irreversibile.
Per altre informazioni, vedere Struttura e definizioni costanti.