Share via


Funzione Entry-Point libreria Dynamic-Link

Una DLL può facoltativamente specificare una funzione del punto di ingresso. Se presente, il sistema chiama la funzione del punto di ingresso ogni volta che un processo o un thread carica o scarica la DLL. Può essere usato per eseguire semplici attività di inizializzazione e pulizia. Ad esempio, può configurare l'archiviazione locale del thread quando viene creato un nuovo thread e pulirlo quando il thread viene terminato.

Se si collega la DLL alla libreria di runtime C, può fornire una funzione punto di ingresso e consentire di fornire una funzione di inizializzazione separata. Per altre informazioni, vedere la documentazione relativa alla libreria di runtime.

Se si specifica il proprio punto di ingresso, vedere la funzione DllMain . Il nome DllMain è un segnaposto per una funzione definita dall'utente. È necessario specificare il nome effettivo usato durante la compilazione della DLL. Per altre informazioni, vedere la documentazione inclusa negli strumenti di sviluppo.

Chiamata della funzione Entry-Point

Il sistema chiama la funzione del punto di ingresso ogni volta che si verifica uno degli eventi seguenti:

  • Un processo carica la DLL. Per i processi che usano il collegamento dinamico in fase di caricamento, la DLL viene caricata durante l'inizializzazione del processo. Per i processi che usano il collegamento in fase di esecuzione, la DLL viene caricata prima che LoadLibrary o LoadLibraryEx restituisca.
  • Un processo scarica la DLL. La DLL viene scaricata quando il processo termina o chiama la funzione FreeLibrary e il conteggio dei riferimenti diventa zero. Se il processo termina come risultato della funzione TerminateProcess o TerminateThread , il sistema non chiama la funzione del punto di ingresso della DLL.
  • Viene creato un nuovo thread in un processo che ha caricato la DLL. È possibile usare la funzione DisableThreadLibraryCalls per disabilitare la notifica quando vengono creati i thread.
  • Un thread di un processo che ha caricato la DLL termina normalmente, non usando TerminateThread o TerminateProcess. Quando un processo scarica la DLL, la funzione del punto di ingresso viene chiamata una sola volta per l'intero processo, anziché una volta per ogni thread esistente del processo. È possibile usare DisableThreadLibraryCalls per disabilitare la notifica quando i thread vengono terminati.

Solo un thread alla volta può chiamare la funzione del punto di ingresso.

Il sistema chiama la funzione del punto di ingresso nel contesto del processo o del thread che ha causato la chiamata della funzione. In questo modo una DLL può usare la funzione del punto di ingresso per l'allocazione della memoria nello spazio degli indirizzi virtuali del processo chiamante o per aprire handle accessibili al processo. La funzione del punto di ingresso può anche allocare memoria privata a un nuovo thread usando l'archiviazione locale del thread (TLS). Per altre informazioni sull'archiviazione locale dei thread, vedere Archiviazione locale thread.

definizione di funzione Entry-Point

La funzione punto di ingresso dll deve essere dichiarata con la convenzione di chiamata standard. Se il punto di ingresso della DLL non è dichiarato correttamente, la DLL non viene caricata e il sistema visualizza un messaggio che indica che il punto di ingresso della DLL deve essere dichiarato con WINAPI.

Nel corpo della funzione è possibile gestire qualsiasi combinazione degli scenari seguenti in cui è stato chiamato il punto di ingresso della DLL:

  • Un processo carica la DLL (DLL_PROCESS_ATTACH).
  • Il processo corrente crea un nuovo thread (DLL_THREAD_ATTACH).
  • Un thread viene chiuso normalmente (DLL_THREAD_DETACH).
  • Un processo scarica la DLL (DLL_PROCESS_DETACH).

La funzione del punto di ingresso deve eseguire solo semplici attività di inizializzazione. Non deve chiamare la funzione LoadLibrary o LoadLibraryEx (o una funzione che chiama queste funzioni), perché ciò può creare cicli di dipendenza nell'ordine di caricamento dll. Ciò può comportare l'uso di una DLL prima che il sistema abbia eseguito il codice di inizializzazione. Analogamente, la funzione del punto di ingresso non deve chiamare la funzione FreeLibrary (o una funzione che chiama FreeLibrary) durante la terminazione del processo, perché ciò può comportare l'uso di una DLL dopo che il sistema ha eseguito il codice di terminazione.

Poiché Kernel32.dll è garantito che venga caricato nello spazio indirizzi del processo quando viene chiamata la funzione del punto di ingresso, la chiamata di funzioni in Kernel32.dll non comporta l'uso della DLL prima dell'esecuzione del codice di inizializzazione. Pertanto, la funzione del punto di ingresso può creare oggetti di sincronizzazione , ad esempio sezioni e mutex critici, e usare TLS, perché queste funzioni si trovano in Kernel32.dll. Non è sicuro chiamare le funzioni del Registro di sistema, ad esempio perché si trovano in Advapi32.dll.

La chiamata ad altre funzioni può causare problemi difficili da diagnosticare. Ad esempio, la chiamata di funzioni User, Shell e COM può causare errori di violazione di accesso, perché alcune funzioni nelle DLL chiamano LoadLibrary per caricare altri componenti di sistema. Al contrario, la chiamata di tali funzioni durante la terminazione può causare errori di violazione di accesso perché il componente corrispondente potrebbe essere già stato scaricato o non inizializzato.

Nell'esempio seguente viene illustrato come strutturare la funzione del punto di ingresso della 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.
}

Valore restituito della funzione Entry-Point

Quando viene chiamata una funzione punto di ingresso DLL perché viene caricato un processo, la funzione restituisce TRUE per indicare l'esito positivo. Per i processi che usano il collegamento in fase di caricamento, un valore restituito FALSE causa l'esito negativo dell'inizializzazione del processo e il processo termina. Per i processi che usano il collegamento in fase di esecuzione, un valore restituito FALSE fa sì che la funzione LoadLibrary o LoadLibraryEx restituisca NULL, a indicare un errore. Il sistema chiama immediatamente la funzione del punto di ingresso con DLL_PROCESS_DETACH e scarica la DLL. Il valore restituito della funzione del punto di ingresso viene ignorato quando la funzione viene chiamata per qualsiasi altro motivo.