Delen via


Dynamic-Link bibliotheekfunctie Entry-Point

Een DLL kan eventueel een invoerpuntfunctie opgeven. Indien aanwezig, roept het systeem de invoerpuntfunctie aan wanneer een proces of thread wordt geladen of het DLL-bestand wordt verwijderd. Het kan worden gebruikt om eenvoudige initialisatie- en opschoontaken uit te voeren. Het kan bijvoorbeeld lokale threadopslag instellen wanneer een nieuwe thread wordt gemaakt en opschonen wanneer de thread wordt beëindigd.

Als u uw DLL koppelt aan de C-runtimebibliotheek, kan deze een invoerpuntfunctie voor u bieden en kunt u een afzonderlijke initialisatiefunctie opgeven. Raadpleeg de documentatie voor uw runtimebibliotheek voor meer informatie.

Als u uw eigen invoerpunt opgeeft, raadpleegt u de functie DllMain. De naam DllMain is een tijdelijke aanduiding voor een door de gebruiker gedefinieerde functie. U moet de werkelijke naam opgeven die u gebruikt bij het bouwen van uw DLL. Zie de documentatie die is opgenomen in uw ontwikkelhulpprogramma's voor meer informatie.

De Entry-Point-functie aanroepen

Het systeem roept de invoerpuntfunctie aan wanneer een van de volgende gebeurtenissen plaatsvindt:

  • Tijdens een proces wordt het DLL-bestand geladen. Voor processen die dynamische koppeling in de laadtijd gebruiken, wordt het DLL-bestand geladen tijdens de initialisatie van het proces. Voor processen die runtimekoppeling gebruiken, wordt het DLL-bestand geladen voordat LoadLibrary- of LoadLibraryEx retourneert.
  • Met een proces wordt het DLL-bestand uitgeladen. Het DLL-bestand wordt uitgeladen wanneer het proces wordt beëindigd of de FreeLibrary- functie aanroept en het aantal verwijzingen nul wordt. Als het proces wordt beëindigd als gevolg van de functie TerminateProcess of TerminateThread, roept het systeem de dll-invoerpuntfunctie niet aan.
  • Er wordt een nieuwe thread gemaakt in een proces dat het DLL-bestand heeft geladen. U kunt de functie DisableThreadLibraryCalls gebruiken om meldingen uit te schakelen wanneer threads worden gemaakt.
  • Een thread van een proces dat het DLL-bestand heeft geladen, wordt normaal beëindigd, niet met behulp van TerminateThread of TerminateProcess. Wanneer een proces het DLL-bestand verwijdert, wordt de invoerpuntfunctie slechts één keer aangeroepen voor het hele proces, in plaats van één keer voor elke bestaande thread van het proces. U kunt DisableThreadLibraryCalls gebruiken om meldingen uit te schakelen wanneer threads worden beëindigd.

Slechts één thread tegelijk kan de invoerpuntfunctie aanroepen.

Het systeem roept de invoerpuntfunctie aan in de context van het proces of de thread waardoor de functie werd aangeroepen. Hierdoor kan een DLL de invoerpuntfunctie gebruiken voor het toewijzen van geheugen in de virtuele adresruimte van het aanroepende proces of het openen van ingangen die toegankelijk zijn voor het proces. De invoerpuntfunctie kan ook geheugen toewijzen die privé is aan een nieuwe thread met behulp van lokale threadopslag (TLS). Zie Thread Local Storagevoor meer informatie over lokale threadopslag.

Entry-Point functiedefinitie

De DLL-invoerpuntfunctie moet worden gedeclareerd met de standaardoproepconventie. Als het DLL-toegangspunt niet juist is gedeclareerd, wordt het DLL-bestand niet geladen en wordt er een bericht weergegeven dat het DLL-toegangspunt moet worden gedeclareerd met WINAPI.

In de hoofdtekst van de functie kunt u elke combinatie van de volgende scenario's verwerken waarin het DLL-toegangspunt is aangeroepen:

  • Een proces laadt het DLL-bestand (DLL_PROCESS_ATTACH).
  • Het huidige proces maakt een nieuwe thread (DLL_THREAD_ATTACH).
  • Een thread wordt normaal afgesloten (DLL_THREAD_DETACH).
  • Met een proces wordt het DLL-bestand (DLL_PROCESS_DETACH) uitgeladen.

De invoerpuntfunctie mag alleen eenvoudige initialisatietaken uitvoeren. Het mag de LoadLibrary- of loadlibraryEx functie (of een functie die deze functies aanroept) niet aanroepen, omdat hiermee afhankelijkheidslussen in de DLL-laadvolgorde kunnen worden gemaakt. Dit kan ertoe leiden dat een DLL wordt gebruikt voordat het systeem de initialisatiecode heeft uitgevoerd. Op dezelfde manier mag de ingangspuntfunctie de functie FreeLibrary (of een functie die FreeLibrary) aanroept tijdens het beëindigen van het proces, niet aanroepen, omdat dit kan resulteren in een DLL die wordt gebruikt nadat het systeem de beëindigingscode heeft uitgevoerd.

Omdat Kernel32.dll gegarandeerd wordt geladen in de adresruimte van het proces wanneer de invoerpuntfunctie wordt aangeroepen, resulteert het aanroepen van functies in Kernel32.dll niet in het DLL-bestand dat wordt gebruikt voordat de initialisatiecode is uitgevoerd. Daarom kan de invoerpuntfunctie synchronisatieobjecten maken, zoals kritieke secties en mutexes, en TLS gebruiken, omdat deze functies zich in Kernel32.dllbevinden. Het is niet veilig om de registerfuncties aan te roepen, bijvoorbeeld omdat ze zich in Advapi32.dllbevinden.

Het aanroepen van andere functies kan leiden tot problemen die moeilijk te diagnosticeren zijn. Als u bijvoorbeeld gebruikers-, Shell- en COM-functies aanroept, kan dit leiden tot fouten met toegangsschendingen, omdat sommige functies in hun DLL's LoadLibrary- aanroepen om andere systeemonderdelen te laden. Omgekeerd kan het aanroepen van deze functies tijdens beëindiging fouten veroorzaken omdat het bijbehorende onderdeel mogelijk al is uitgepakt of niet geïnitialiseerd.

In het volgende voorbeeld ziet u hoe u de DLL-invoerpuntfunctie kunt structuren.

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.
}

retourwaarde Entry-Point functie

Wanneer een DLL-invoerpuntfunctie wordt aangeroepen omdat een proces wordt geladen, retourneert de functie TRUE om aan te geven dat het is gelukt. Voor processen die load-time-koppeling gebruiken, retourwaarde van FALSE ervoor zorgt dat de procesinitialisatie mislukt en het proces wordt beëindigd. Voor processen die runtimekoppeling gebruiken, veroorzaakt een retourwaarde ONWAAR de LoadLibrary- of functie LoadLibraryEx om NULL-te retourneren, wat een fout aangeeft. (Het systeem roept onmiddellijk uw invoerpuntfunctie aan met DLL_PROCESS_DETACH en verwijdert het DLL-bestand.) De retourwaarde van de invoerpuntfunctie wordt genegeerd wanneer de functie om een andere reden wordt aangeroepen.