Partager via


Dynamic-Link Library Entry-Point Function

Une DLL peut éventuellement spécifier une fonction de point d’entrée. Le cas échéant, 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 lors de la création d’un nouveau thread et le propre lorsque le thread est terminé.

Si vous liez votre DLL à la bibliothèque d’exécution C, elle peut vous fournir une fonction de point d’entrée et vous permettre de fournir une fonction d’initialisation distincte. Pour plus d’informations, consultez la documentation relative à 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 qu’un des événements suivants se produit :

  • Un processus charge la DLL. Pour les processus qui utilisent 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 que LoadLibrary ou LoadLibraryEx ne retourne.
  • Un processus décharge la DLL. La DLL est déchargée lorsque le processus se termine ou appelle la fonction FreeLibrary et que le nombre de références devient égal à 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 lors de la création de threads.
  • 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 n’est appelée qu’une seule fois pour l’ensemble du processus, plutôt qu’une 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 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 des threads, consultez Stockage local des threads.

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 de 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 se ferme normalement (DLL_THREAD_DETACH).
  • Un processus décharge la DLL (DLL_PROCESS_DETACH).

La fonction de point d’entrée ne doit effectuer que des tâches d’initialisation simples. Il ne doit pas appeler la fonction LoadLibrary ou LoadLibraryEx (ou une fonction qui appelle ces fonctions), car cela peut créer des boucles de dépendance dans l’ordre de chargement de 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 une fois que le système a exécuté son code d’arrêt.

Étant donné que Kernel32.dll est 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 des sections critiques et des mutex, et utiliser TLS, car ces fonctions se trouvent dans Kernel32.dll. Il n’est pas sûr d’appeler les fonctions du 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 provoquer 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 a peut-être déjà é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 en cours de chargement, la fonction retourne TRUE pour indiquer la réussite. Pour les processus qui utilisent la liaison au temps de chargement, une valeur de retour FALSE entraîne l’échec de l’initialisation du processus et l’arrêt du processus. Pour les processus qui utilisent la liaison au moment de l’exécution, une valeur de retour FALSE entraîne le retour de la fonction LoadLibrary ou LoadLibraryEx à la valeur NULL, ce qui indique un é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.