Dynamic-Link fonction Entry-Point bibliothèque
Une DLL peut éventuellement spécifier une fonction de point d’entrée. S’il est présent, le système appelle la fonction de point d’entrée chaque fois qu’un processus ou un thread charge ou décharge la DLL. Il peut être utilisé pour effectuer des tâches d’initialisation et de nettoyage simples. Par exemple, il peut configurer le stockage local de thread lorsqu’un nouveau thread est créé et le nettoyer lorsque le thread est arrêté.
Si vous liez votre DLL à la bibliothèque runtime C, elle peut fournir une fonction de point d’entrée pour vous et vous permettre de fournir une fonction d’initialisation distincte. Pour plus d’informations, consultez la documentation de votre bibliothèque d’exécution.
Si vous fournissez votre propre point d’entrée, consultez la fonction DllMain. Le nom DllMain est un espace réservé pour une fonction définie par l’utilisateur. Vous devez spécifier le nom réel que vous utilisez lorsque vous générez votre DLL. Pour plus d’informations, consultez la documentation fournie avec vos outils de développement.
Appel de la fonction Entry-Point
Le système appelle la fonction de point d’entrée chaque fois que l’un des événements suivants se produit :
- Un processus charge la DLL. Pour les processus utilisant la liaison dynamique au moment du chargement, la DLL est chargée pendant l’initialisation du processus. Pour les processus utilisant la liaison au moment de l’exécution, la DLL est chargée avant LoadLibrary ou LoadLibraryEx retourne.
- Un processus décharge la DLL. La DLL est déchargée lorsque le processus se termine ou appelle la fonction FreeLibrary et le nombre de références devient zéro. Si le processus se termine à la suite de la fonction TerminateProcess ou TerminateThread, le système n’appelle pas la fonction de point d’entrée DLL.
- Un nouveau thread est créé dans un processus qui a chargé la DLL. Vous pouvez utiliser la fonction DisableThreadLibraryCalls pour désactiver la notification lorsque des threads sont créés.
- Un thread d’un processus qui a chargé la DLL se termine normalement, sans utiliser TerminateThread ou TerminateProcess. Lorsqu’un processus décharge la DLL, la fonction de point d’entrée est appelée une seule fois pour l’ensemble du processus, plutôt qu’une seule fois pour chaque thread existant du processus. Vous pouvez utiliser DisableThreadLibraryCalls pour désactiver la notification lorsque les threads sont arrêtés.
Un seul thread à la fois peut appeler la fonction de point d’entrée.
Le système appelle la fonction de point d’entrée dans le contexte du processus ou du thread qui a provoqué l’appel de la fonction. Cela permet à une DLL d’utiliser sa fonction de point d’entrée pour allouer de la mémoire dans l’espace d’adressage virtuel du processus appelant ou d’ouvrir des handles accessibles au processus. La fonction de point d’entrée peut également allouer de la mémoire privée à un nouveau thread à l’aide du stockage local de thread (TLS). Pour plus d’informations sur le stockage local de threads, consultez de stockage local thread .
définition de fonction Entry-Point
La fonction de point d’entrée DLL doit être déclarée avec la convention d’appel standard. Si le point d’entrée DLL n’est pas déclaré correctement, la DLL n’est pas chargée et le système affiche un message indiquant que le point d’entrée DLL doit être déclaré avec WINAPI.
Dans le corps de la fonction, vous pouvez gérer n’importe quelle combinaison des scénarios suivants dans lesquels le point d’entrée DLL a été appelé :
- Un processus charge la DLL (DLL_PROCESS_ATTACH).
- Le processus actuel crée un thread (DLL_THREAD_ATTACH).
- Un thread s’arrête normalement (DLL_THREAD_DETACH).
- Un processus décharge la DLL (DLL_PROCESS_DETACH).
La fonction de point d’entrée doit effectuer uniquement des tâches d’initialisation simples. Il ne doit pas appeler la fonction LoadLibrary ou LoadLibraryEx function (ou une fonction qui appelle ces fonctions), car cela peut créer des boucles de dépendance dans l’ordre de chargement dll. Cela peut entraîner l’utilisation d’une DLL avant que le système n’ait exécuté son code d’initialisation. De même, la fonction de point d’entrée ne doit pas appeler la fonction FreeLibrary (ou une fonction qui appelle freeLibrary) pendant l’arrêt du processus, car cela peut entraîner l’utilisation d’une DLL après que le système a exécuté son code d’arrêt.
Étant donné que Kernel32.dll est garanti être chargé dans l’espace d’adressage du processus lorsque la fonction de point d’entrée est appelée, l’appel de fonctions dans Kernel32.dll n’entraîne pas l’utilisation de la DLL avant l’exécution de son code d’initialisation. Par conséquent, la fonction de point d’entrée peut créer des objets de synchronisation tels que les sections critiques et les mutex, et utiliser TLS, car ces fonctions se trouvent dans Kernel32.dll. Il n’est pas sûr d’appeler les fonctions de Registre, par exemple, car elles se trouvent dans Advapi32.dll.
L’appel d’autres fonctions peut entraîner des problèmes difficiles à diagnostiquer. Par exemple, l’appel des fonctions User, Shell et COM peut entraîner des erreurs de violation d’accès, car certaines fonctions de leurs DLL appellent LoadLibrary pour charger d’autres composants système. À l’inverse, l’appel de ces fonctions pendant l’arrêt peut entraîner des erreurs de violation d’accès, car le composant correspondant peut déjà avoir été déchargé ou non initialisé.
L’exemple suivant montre comment structurer la fonction de point d’entrée DLL.
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
valeur de retour de fonction Entry-Point
Lorsqu’une fonction de point d’entrée DLL est appelée parce qu’un processus est chargé, la fonction retourne TRUE pour indiquer la réussite. Pour les processus utilisant la liaison au temps de chargement, une valeur de retour de FAUX provoque l’échec de l’initialisation du processus et le processus se termine. Pour les processus utilisant la liaison au moment de l’exécution, une valeur de retour de FALSE entraîne laLoadLibraryou fonction LoadLibraryEx de retourner NULL, indiquant l’échec. (Le système appelle immédiatement votre fonction de point d’entrée avec DLL_PROCESS_DETACH et décharge la DLL.) La valeur de retour de la fonction de point d’entrée est ignorée lorsque la fonction est appelée pour toute autre raison.