Dynamic Link Libraries Inside-Out - The DLL Entry Point Function: DllMain
(Page 4 of 9 )
A DLL can contain many functions but the Entry point function is special. As explained by the MSDN library, the DllMain function is an optional entry point into a DLL. If the function is used, it is called by the system when processes and threads are initialized and terminated, or upon calls to the LoadLibrary and FreeLibrary functions. DllMain name is just a placeholder for the library-defined function name. You must specify the actual name you use when you build your DLL. This function is a bit different from the other functions that the DLL contains in the sense that it allows us to do specific initialization or clan-up as per our requirements. Let’s have a look at the DllMain function in code:
HINSTANCE g_hInstance;
BOOL WINAPI DllMain(HINSTANCE hInstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
g_hInstance = hInstDLL;
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
It provides us four places that we can use to do application specific cleanup or initialization. They are:
• DLL_PROCESS_ATTACH: This is the parameter sent in the fdwReason parameter if some process loaded the DLL for the first time. If we are not using some shared data among DLL instances, then each application using this DLL will have its private copy of DLL data. This means the programmer is free to do any initialization. But how can someone know what program loaded the DLL. It’s simple, just call the GetModuleFileName API with NULL as the instance handle. This will give you the name of the application in whose context this handler is executing. This really can make a big contribution if you intend to do application specific initialization. Just make sure to return a TRUE from this function if you want the DLL to load successfully or else it’ll fail, causing the application to fail or unload if it’s linked implicitly (we’re going to discuss that in the next section).
• DLL_THREAD_ATTACH: This is similar to the DLL_PROCESS_ATTACH case but is invoked when a thread tries to use a function from the DLL.
• DLL_THREAD_DETACH: This is the complement of the above DLL_THREAD_ATTACH case and is invoked when a thread detaches from the DLL or finishes using this DLL or explicitly calls FreeLibrary API. You may perform any cleanup of resources that you allocated in DLL_THREAD_ATTACH handler.
• DLL_PROCESS_DETACH: This is the complement of the DLL_PROCESS_ATTACH case and is invoked when a process detaches from the DLL or finishes using this DLL or explicitly calls FreeLibrary API. You may perform any cleanup of resources that you allocated in DLL_THREAD_ATTACH handler.
One may disable the DLL_THREAD_ATTACH and DLL_THREAD_DETACH cases while the DLL loads by calling DisableThreadLibraryCalls API. Another point to note that if some memory allocation is to be done in context of the DLL in the entry point function, one should use the TlsAlloc and TlsFree APIs to do so. TLS stands for Thread Local Storage.
Next: Types of DLL Linking >>
More Code Examples Articles
More By Digvijay Chauhan