Notificación y control de errores
Si el programa usa archivos DLL cargados con retraso, debe controlar los errores de forma sólida, ya que los errores que se producen mientras se ejecuta el programa producirán excepciones no controladas. El control de errores se compone de dos partes: recuperación a través de un enlace e informes a través de una excepción.
Para obtener más información sobre el control y la notificación de errores de carga retrasada de DLL, consulte Descripción de la función auxiliar.
Para obtener más información sobre las funciones de enlace, vea Definiciones de estructura y constantes.
Recuperación a través de un enlace
Es posible que el código tenga que recuperarse en caso de error o para proporcionar una biblioteca o rutina alternativa. Puede proporcionar un enlace a la función auxiliar que puede proporcionar el código alternativo o solucionar la situación. La rutina de enlace debe devolver un valor adecuado para que el procesamiento pueda continuar (HINSTANCE
o FARPROC
). O bien, puede devolver 0 para indicar que se debe producir una excepción. También podría producir su propia excepción o longjmp
fuera del enlace. Hay enlaces de notificación y enlaces de error. Se puede usar la misma rutina para ambos.
Enlaces de notificación
Se llama a los enlaces de notificación de carga de retraso justo antes de que se realicen las siguientes acciones en la rutina del asistente:
El identificador almacenado en la biblioteca se comprueba para ver si ya se ha cargado.
LoadLibrary
se llama a para intentar la carga del archivo DLL.GetProcAddress
se llama a para intentar obtener la dirección del procedimiento.Vuelva al código de carga de importación de retraso.
El enlace de notificación está habilitado:
Al proporcionar una nueva definición del puntero
__pfnDliNotifyHook2
que se inicializa para que apunte a su propia función que recibe las notificaciones.O bien
Al establecer el puntero
__pfnDliNotifyHook2
a la función de enlace antes de cualquier llamada al archivo DLL que el programa está retrasando la carga.
Si la notificación es dliStartProcessing
, la función de enlace puede devolver:
NULL
El asistente predeterminado controla la carga del archivo DLL. Es útil llamar a solo con fines informativos.
Puntero de función.
Omita el control de carga de retraso predeterminado. Le permite suministrar su propio controlador de carga.
Si la notificación es dliNotePreLoadLibrary
, la función de enlace puede devolver:
0, si solo quiere notificaciones informativas.
HMODULE
para el archivo DLL cargado, si cargó el propio archivo DLL.
Si la notificación es dliNotePreGetProcAddress
, la función de enlace puede devolver:
0, si solo quiere notificaciones informativas.
La dirección de la función importada, si la función de enlace obtiene la propia dirección.
Si la notificación es dliNoteEndProcessing
, se omite el valor devuelto de la función de enlace.
Si este puntero se inicializa (distinto de cero), el asistente de carga retrasada invoca la función en determinados puntos de notificación a lo largo de su ejecución. El puntero de función tiene la siguiente definición:
// 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;
Las notificaciones pasan una estructura DelayLoadInfo
a la función de enlace junto con el valor de notificación. Estos datos son idénticos a los datos utilizados por la rutina auxiliar de carga retrasada. El valor de notificación será uno de los valores definidos en Estructura y definiciones de constantes.
Enlaces de error
El enlace de error está habilitado de la misma manera que el enlace de notificación. La rutina de enlace debe devolver un valor adecuado para que el procesamiento pueda continuar (HINSTANCE
o FARPROC
) o 0 para indicar que se debe iniciar una excepción.
La variable de puntero que hace referencia a la función definida por el usuario es:
// This is the failure hook, dliNotify = {dliFailLoadLib|dliFailGetProc}
ExternC
PfnDliHook __pfnDliFailureHook2;
La estructura DelayLoadInfo
contiene todos los datos pertinentes necesarios para la notificación detallada del error, incluido el valor de GetLastError
.
Si la notificación es dliFailLoadLib
, la función de enlace puede devolver:
0, si no puede controlar el error.
HMODULE
, si el enlace de error corrigió el problema y cargó la propia biblioteca.
Si la notificación es dliFailGetProc
, la función de enlace puede devolver:
0, si no puede controlar el error.
Una dirección de procedimiento válida (dirección de función de importación), si el enlace de error se realizó correctamente para obtener la propia dirección.
Informe mediante una excepción
Si todo lo necesario para controlar el error es anular el procedimiento, no es necesario ningún enlace, siempre y cuando el código de usuario pueda controlar la excepción.
Retrasar códigos de excepción de carga
Los códigos de excepción estructurados se pueden generar cuando se producen errores durante una carga retrasada. Los valores de excepción se especifican mediante una macro VcppException
:
//
// Exception information
//
#define FACILITY_VISUALCPP ((LONG)0x6d)
#define VcppException(sev,err) ((sev) | (FACILITY_VISUALCPP<<16) | err)
Para un error LoadLibrary
, se produce el estándar VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND)
. Para un error GetProcAddress
, el error producido es VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND)
. La excepción pasa un puntero a una estructura DelayLoadInfo
. Está en el valor LPDWORD
recuperado por GetExceptionInformation
de la estructura EXCEPTION_RECORD
, en el campo ExceptionInformation[0]
.
Si los bits incorrectos se establecen en el campo grAttrs
, se produce la excepción ERROR_INVALID_PARAMETER
. Esta excepción es, para todas las intenciones y propósitos, irrecuperables.
Para obtener más información, vea Definiciones de estructura y constantes.
Consulte también
Compatibilidad del vinculador con archivos DLL cargados con retraso