Zpracování chyb a oznámení
Pokud váš program používá knihovny DLL s odloženým načtením, musí zpracovávat chyby robustně, protože selhání, ke kterým dochází při spuštění programu, způsobí neošetřené výjimky. Zpracování selhání se skládá ze dvou částí: Obnovení prostřednictvím háku a generování sestav prostřednictvím výjimky.
Další informace o zpracování chyb a oznámení o zpoždění načítání knihovny DLL naleznete v tématu Vysvětlení pomocné funkce.
Další informace o funkcích háku naleznete v tématu Struktury a definice konstant.
Obnovení prostřednictvím háku
Kód může být potřeba obnovit v případě selhání nebo poskytnout alternativní knihovnu nebo rutinu. Můžete poskytnout háček pomocné funkci, která může poskytnout alternativní kód nebo napravit situaci. Rutina háku musí vrátit vhodnou hodnotu, aby zpracování bylo možné pokračovat ( HINSTANCE
nebo FARPROC
). Nebo může vrátit hodnotu 0, která značí, že by se měla vyvolat výjimka. Může také vyvolat vlastní výjimku nebo longjmp
z háku. K dispozici jsou háky oznámení a selhání. Stejnou rutinu lze použít pro oba.
Hooky oznámení
Háky oznámení o zpoždění se volají těsně před provedením následujících akcí v pomocné rutině:
Uložený popisovač knihovny je zaškrtnutý a zkontroluje, jestli už byl načten.
LoadLibrary
je volána k pokusu o načtení knihovny DLL.GetProcAddress
je volána k pokusu o získání adresy procedury.Vraťte se do bloku načítání importu zpoždění.
Aktivuje se oznamovací hák:
Zadáním nové definice ukazatele
__pfnDliNotifyHook2
, který je inicializován tak, aby odkazovat na vlastní funkci, která přijímá oznámení.nebo
Nastavením ukazatele
__pfnDliNotifyHook2
na funkci háku před všemi voláními knihovny DLL, které program zpožďuje načítání.
Pokud je dliStartProcessing
oznámení, funkce háku může vrátit:
NULL
Výchozí pomocník zpracovává načítání knihovny DLL. Je užitečné volat jen pro informační účely.
ukazatel funkce
Obejití výchozího zpracování zpoždění při načítání. Umožňuje zadat vlastní obslužnou rutinu načítání.
Pokud je dliNotePreLoadLibrary
oznámení, funkce háku může vrátit:
0, pokud chce jenom informační oznámení.
Pro
HMODULE
načtenou knihovnu DLL, pokud načetla samotnou knihovnu DLL.
Pokud je dliNotePreGetProcAddress
oznámení, funkce háku může vrátit:
0, pokud chce jenom informační oznámení.
Adresa importované funkce, pokud funkce háku získá adresu samotnou.
Pokud je dliNoteEndProcessing
oznámení, návratová hodnota funkce háku se ignoruje.
Pokud je tento ukazatel inicializován (nenulový), pomocník pro načtení zpoždění vyvolá funkci v určitých oznamovacích bodech během jeho provádění. Ukazatel funkce má následující definici:
// 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;
Oznámení předávají DelayLoadInfo
struktuře funkci háku spolu s hodnotou oznámení. Tato data jsou stejná jako data používaná rutinou pomocné rutiny načítání zpoždění. Hodnota oznámení bude jednou z hodnot definovaných v definicích struktury a konstanty.
Hooky selhání
Háček selhání je povolený stejným způsobem jako oznámení. Rutina háku musí vrátit vhodnou hodnotu, aby zpracování bylo možné pokračovat ( HINSTANCE
nebo FARPROC
) nebo 0, aby bylo možné označit, že by měla být vyvolán výjimka.
Proměnná ukazatele, která odkazuje na uživatelem definovanou funkci, je:
// This is the failure hook, dliNotify = {dliFailLoadLib|dliFailGetProc}
ExternC
PfnDliHook __pfnDliFailureHook2;
Struktura DelayLoadInfo
obsahuje všechna příslušná data potřebná k podrobnému hlášení chyby, včetně hodnoty z GetLastError
.
Pokud je dliFailLoadLib
oznámení, funkce háku může vrátit:
0, pokud nemůže zpracovat chybu.
Pokud
HMODULE
háček selhání problém vyřešil a načetl samotnou knihovnu.
Pokud je dliFailGetProc
oznámení, funkce háku může vrátit:
0, pokud nemůže zpracovat chybu.
Platná adresa proc (adresa funkce importu), pokud se selhání háku podařilo získat samotnou adresu.
Sestava pomocí výjimky
Pokud je pro zpracování chyby potřeba vše, je přerušit proceduru, není potřeba žádný háček, pokud uživatelský kód dokáže zpracovat výjimku.
Kódy výjimek zpoždění načtení
Strukturované kódy výjimek je možné zvýšit, když dojde k selhání během zpožděného zatížení. Hodnoty výjimek se zadají pomocí VcppException
makra:
//
// Exception information
//
#define FACILITY_VISUALCPP ((LONG)0x6d)
#define VcppException(sev,err) ((sev) | (FACILITY_VISUALCPP<<16) | err)
V případě LoadLibrary
selhání je vyvolán standard VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND)
. V případě GetProcAddress
selhání je VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND)
vyvolán chyba . Výjimka předá ukazatel do DelayLoadInfo
struktury. Je v hodnotě LPDWORD
načtené GetExceptionInformation
ze EXCEPTION_RECORD
struktury v ExceptionInformation[0]
poli.
Pokud jsou v grAttrs
poli nastaveny nesprávné bity, vyvolá se výjimka ERROR_INVALID_PARAMETER
. Tato výjimka je pro všechny záměry a účely závažná.
Další informace naleznete v tématu Struktury a definice konstant.