When the application calls the LoadLibrary or LoadLibraryEx functions, the system attempts to locate the DLL using the same search sequence used in load-time dynamic linking (see Load-Time Dynamic Linking). If the search succeeds, the system maps the DLL module into the virtual address space of the process and increments the reference count. If the call to LoadLibrary or LoadLibraryEx specifies a DLL whose code is already mapped into the virtual address space of the calling process, the function simply returns a handle to the DLL and increments the DLL reference count. Note that two DLLs that have the same base filename and extension but are found in different directories are not considered to be the same DLL.
The operating system calls the entry-point function in the context of the thread that called LoadLibrary or LoadLibraryEx. The entry-point function is not called if the DLL was already loaded by the process through a call to LoadLibrary or LoadLibraryEx with no corresponding call to the FreeLibrary function.
If the system cannot find the DLL or if the entry-point function returns FALSE, LoadLibrary or LoadLibraryEx returns NULL. If LoadLibrary or LoadLibraryEx succeeds, it returns a handle of the DLL module. The process can use this handle to identify the DLL in a call to the GetProcAddress, FreeLibrary, or FreeLibraryAndExitThread function.
The GetModuleHandle function returns a handle used in GetProcAddress, FreeLibrary, or FreeLibraryAndExitThread. The GetModuleHandle function succeeds only if the DLL module is already mapped into the address space of the process by load-time linking or by a previous call to LoadLibrary or LoadLibraryEx. Unlike LoadLibrary or LoadLibraryEx, GetModuleHandle does not increment the module reference count. The GetModuleFileName function retrieves the full path of the module associated with a handle returned by GetModuleHandle, LoadLibrary, or LoadLibraryEx.
The process can use GetProcAddress to get the address of an exported function in the DLL using a DLL module handle returned by either LoadLibrary, LoadLibraryEx, or GetModuleHandle.
When the DLL module is no longer needed, the process can call FreeLibrary or FreeLibraryAndExitThread. These functions decrement the module reference count and unmap the DLL code from the virtual address space of the process if the reference count is zero.
Run-time dynamic linking enables the process to continue running even if a DLL is not available. The process can then use an alternate method to accomplish its objective. For example, if a process is unable to locate one DLL, it can try to use another, or it can notify the user of an error. If the user can provide the full path of the missing DLL, the process can use this information to load the DLL even though it is not in the normal search path. This situation contrasts with load-time linking, in which the operating system simply terminates the process if it cannot find the DLL.
Run-time dynamic linking can cause problems if the DLL uses the DllEntryPoint function to perform initialization for each thread of a process, because the entry-point is not called for threads that existed before LoadLibrary or LoadLibraryEx is called. For an example showing how to deal with this problem, see Using Thread Local Storage in a Dynamic-Link Library.