Platform SDK: DLLs, Processes, and Threads

Dynamic-Link Library Entry-Point Function

Every DLL must have an entry point, just as an application does. The system calls the entry-point function whenever processes and threads load or unload the DLL. If you are linking your DLL with a library, such as the C run-time library, it may provide an entry-point function for you, and allow you to provide a separate initialization function. Check the documentation for your run-time library for more information.

If you are providing your own entry-point, see the DllMain function. The name DllMain is a placeholder for a user-defined function. Earlier versions of the SDK documentation used DllEntryPoint as the entry-point function name. You must specify the actual name you use when you build your DLL. For more information, see the documentation included with your development tools.

Calling the Entry-Point Function

The system calls the entry-point function whenever any one of the following events occurs:

Only one thread at a time can call the entry-point function.

The system calls the entry-point function in the context of the process or thread that caused the function to be called. This allows a DLL to use its entry-point function for allocating memory in the virtual address space of the calling process or to open handles accessible to the process. The entry-point function can also allocate memory that is private to a new thread by using thread local storage (TLS). For more information about thread local storage, see Thread Local Storage.

Entry-Point Function Definition

The DLL entry-point function must be declared with the standard-call calling convention.

Windows NT/ 2000: If the DLL entry point is not declared correctly, the DLL is not loaded, and the system displays a message indicating that the DLL entry point must be declared with WINAPI.

Windows 95: If the DLL entry point is not declared correctly, the DLL is not loaded and the system displays a message titled "Error starting program," which instructs the user to check the file to determine the problem.

In the body of the function, you may handle any combination of the following scenarios in which the DLL entry point has been called:

Your function should perform only simple initialization tasks, such as setting up thread local storage (TLS), creating synchronization objects, and opening files. It must not call the LoadLibrary function, because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, you must not call the FreeLibrary function in the entry-point function, because this can result in a DLL being used after the system has executed its termination code.

Calling Win32 functions other than TLS, synchronization, and file functions may also result in problems that are difficult to diagnose. For example, calling User, Shell, and COM functions can cause access violation errors, because some functions in their DLLs call LoadLibrary to load other system components.

The following example demonstrates how to structure the DLL entry-point function.

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

Entry-Point Function Return Value

When a DLL entry-point function is called because a process is loading, the function returns TRUE to indicate success. For processes using load-time linking, a return value of FALSE causes the process initialization to fail and the process terminates. For processes using run-time linking, a return value of FALSE causes the LoadLibrary or LoadLibraryEx function to return NULL, indicating failure. (The system immediately calls your entry-point function with DLL_PROCESS_DETACH and unloads the DLL.) The return value of the entry-point function is disregarded when the function is called for any other reason.