A version of this page is also available for
This function is an optional method of entry into a DLL.
DllMain is a placeholder for the library-defined function name.
You must specify the name you use when you build your DLL.
For more information, see the documentation included with your development tools.
BOOL WINAPI DllMain( HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved );
[in] Handle to the DLL.
The value is the base address of the DLL.
The HINSTANCE of a DLL is the same as the HMODULE of the DLL, so hinstDLL can be used in subsequent calls to the GetModuleFileName function and other functions that require a module handle.
[in] Specifies a flag indicating why the DLL entry-point function is being called.
This parameter can be set to one of the following values.
Indicates that the DLL is being loaded into the virtual address space of the current process as a result of the process starting or as a result of a call to LoadLibrary.
DLLs can use this opportunity to initialize instance data or to use the TlsAlloc function to allocate a thread local storage (TLS) index.
If you receive thread creation and deletion notifications, a DLL loaded into the kernel is not calling DisableThreadLibraryCalls. DLL notification in the kernel affects performance. Therefore, if a DLL is loaded in the kernel and the DLL does not need to get a thread exit notification, the DLL should call the DisableThreadLibraryCalls function in DLL_PROCESS_ATTACH.
Indicates that the current process is creating a thread.
When this occurs, the system calls the entry-point function of all DLLs attached to the process. The call is made in the context of the new thread.
DLLs can use this opportunity to initialize a TLS slot for the thread.
A thread calling the DLL entry-point function with DLL_PROCESS_ATTACH does not call the DLL entry-point function with DLL_THREAD_ATTACH.> [!NOTE] > The entry point of a DLL function is called with this value only by threads created after the DLL is loaded by the process. > [!NOTE] > When a DLL is loaded using LoadLibrary, existing threads do not call the entry-point function of the newly loaded DLL.
Indicates that the DLL is being unloaded from the virtual address space of the calling process as a result of either a process exit or a call to FreeLibrary.
The DLL can use this opportunity to call the TlsFree function to free TLS indexes allocated by using TlsAlloc and to free thread-local data.
Indicates that a thread is exiting cleanly.
If the DLL has stored a pointer to allocated memory in a TLS slot, it uses this opportunity to free the memory.
The system calls the entry-point function of all loaded DLLs with this value.
The call is made in the context of the exiting thread.
[in] Specifies further aspects of DLL initialization and cleanup.
If dwReason is DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads and nonnull for static loads.
If dwReason is DLL_PROCESS_DETACH, lpvReserved is NULL if DllMain is called by using FreeLibrary and nonnull if DllMain is called during process termination.
When the system calls the DllMain function with the DLL_PROCESS_ATTACH value, the function returns TRUE if it succeeds or FALSE if initialization fails.
If the return value is FALSE when DllMain is called because the process uses the LoadLibrary function, LoadLibrary returns NULL.
If the return value is FALSE when DllMain is called during process initialization, the process terminates with an error. To get extended error information, call GetLastError.
When the system calls the DllMain function with a value other than DLL_PROCESS_ATTACH, the return value is ignored.
During initial process startup or after a call to LoadLibrary, the system scans the list of loaded DLLs for the process.
For each DLL that is not called with the DLL_PROCESS_ATTACH value, the system calls the entry-point function of the DLL. This call is made in the context of the thread that caused the process address space to change, such as the primary thread of the process or the thread that called LoadLibrary.
There are cases when the entry-point function is called for a terminating thread even if the DLL never attached to the thread — for example, if the entry-point function was not called with the DLL_THREAD_ATTACH value in the context of the thread in these situations:
- The thread was the initial thread in the process, so the system called the entry-point function with the DLL_PROCESS_ATTACH value.
- The thread was already running when a call to the LoadLibrary function was made, so the system never called the entry-point function for it.
When a DLL is unloaded from a process as a result of process termination or as a result of a call to FreeLibrary, the system does not call the entry-point function of the DLL with the DLL_THREAD_DETACH value for the individual threads of the process. The DLL is only given DLL_PROCESS_DETACH notification.
DLLs can take this opportunity to clean up resources for threads known to the DLL.
On attach, the body of your DLL entry-point function should perform only simple initialization tasks, such as the following:
- Setting up thread local storage (TLS).
- Creating synchronization objects.
- Opening files.
Do not call LoadLibrary in the entry-point function, because you might create dependency loops in the DLL load order. This can cause a DLL to be used before the system executes its initialization code.
Similarly, do not call the FreeLibrary function in the entry-point function on detach, because this can cause a DLL to be used after the system executes its termination code.
Calling Microsoft® Win32® functions other than TLS, object-creation, and file functions can cause problems that are difficult to diagnose.
For example, calling User, Shell, COM, and Windows Sockets functions (or functions that call these functions) can cause access violation errors, because their DLLs call LoadLibrary to load other system components.
Although it is acceptable to create synchronization objects in DllMain, do not perform synchronization in DllMain (or a function called by DllMain), because all calls to DllMain are serialized. Waiting on synchronization objects in DllMain can cause a deadlock.
To provide more complex initialization, create an initialization routine for the DLL.
You can require applications to call the initialization routine before calling other routines in the DLL. Otherwise, you can have the initialization routine create a named mutex, and have each routine in the DLL call the initialization routine if the mutex does not exist.
|Windows Embedded CE||Windows CE 1.0 and later|
|Windows Mobile||Windows Mobile Version 5.0 and later|