DLL-related stuff
1. How to load DLL
Implicit:
#pragma comment (lib, "XX.lib");
The compiler went to find a DLL named XX.dll, which, in addition to the same name, has the same GUID as the lib.
An explicit:
HInstance HInst = LoadLibrary (TEXT ("XX.dll"));
if (NULL = = hInst) Retrun;
HInstance HInst = LoadLibrary (TEXT ("XX.dll"), NULL, FLAGS);
The third parameter is a few flags, see core programming.
2. DLL Entry function
Prototype
BOOL apientry DllMain (hmodule hmodule,
DWORD Ul_reason_for_call,
LPVOID lpreserved
);
Where Hmodule is the location of the DLL in the current process address space, Ul_reason_for_call is the reason for calling this function, lpreserved if it is an explicit load or 0 if it is implicitly loaded, it is not 0.
Tell me a little bit about Ul_reason_for_call
BOOL apientry DllMain(hmodule hmodule, DWORD Ul_reason_for_call, LPVOID lpreserved) {#ifdef _DEBUGSwitch(ul_reason_for_call) {//called only once when the DLL is loaded into the address space for the first time//the DLL is then loaded into the address space of the different processes so that it does not call//When the keynote thread calls the DllMain function through the reason, the keynote thread does not receive a DLL_THREAD_ATTACH notification Casedll_process_attach:outputdebugstring (TEXT ("\r\n***********b Dll Dll_process_attach ***********\r\n")); Break; //When the DLL has been loaded into the process address space, the newly created thread executes this code first when there is a new "thread creation"//and then execute the code for the thread itself.//no matter how many DLLs, each DLL's code here is executed by the new thread Casedll_thread_attach:outputdebugstring (TEXT ("\r\n***********b Dll Dll_thread_attach ***********\r\n")); Break; //When the DLL has already been loaded into the process address space, the thread ends up calling the code here before it ends.//Before returning//no matter how many DLLs, each DLL's code here is executed Casedll_thread_detach:outputdebugstring (TEXT ("\r\n***********b Dll dll_thread_detach *********** \ r \ n")); Break; //It is called only once when the DLL is unloaded from memory Casedll_process_detach:outputdebugstring (TEXT ("\r\n***********b Dll Dll_process_detach ***********\r\n")); Break; }#endif returnTRUE;}
Demo
There are two DLLs, ADll.dll and BDll.dll
Load this two DLL in the program, and then create a new thread to see the output
//Load DLLvoidCuseabdlldlg::onbnclickedbtnloadlib () {hinstance Hinsta= LoadLibrary (_t ("ADll.dll")); HINSTANCE HINTB= LoadLibrary (_t ("BDll.dll")); if(NULL = = Hinsta | | NULL = =HINTB) {AfxMessageBox (_t ("failed to load DLL")); return; } }//Thread FunctionsUINT WINAPI workthread (lpvoid lpparam) {#ifdef _DEBUG OutputDebugString (TEXT ("\r\n&&&&&&&&&&&&&&&&&& thread is created & &&&&&&&&&&&&&&&&\r\n"));#endif return 0U;}//Creating ThreadsvoidCuseabdlldlg::onbnclickedbutton2 () {HANDLE hthread= (HANDLE) _beginthreadex (NULL,0, Workthread, NULL,0, NULL); if(NULL = = Hthread | | Invalid_handle_value = =hthread) {AfxMessageBox (_t ("failed to create thread")); }}
Output
Conclusion:
Each time a new thread is created, the DllMain function of the DLL in the current process address space is called once through the Dll_thread_attach notification
For each end of a thread, the DllMain function of the empty DLL in the process address space is called once through the Dll_thread_detach notification.