티스토리 뷰


이전에 DllMain이 왜 안되었을까...살펴보니 그이유가..

DllMain안에다가 전역변수를 그대로 카피n페이스트하다가 int g_nWindowSize = 10;을 그대로 복사해버렸던 것이다-_-;;

DllMain은 제대로 되는건데 내 실수가 잠시 DllMain을 회피하게 만들었다;;그럼 초기화와 해제를 하기 위해 DllMain에 대해 한번 알아보자..

먼저 MSDN에 있는 내용..이것만 읽어도 충분히 활용할 수 있다.

DllMain

The DllMain function is an optional entry point into a dynamic-link library (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.

Warning  There are serious limits on what you can do in a DLL entry point. To provide more complex initialization, create an initialization routine for the DLL. You can require applications to call the initialization routine before calling any other routines in the DLL. Alternatively, the initialization routine can create a file with an ACL that restricts access, and each routine in the DLL would call the initialization routine if the file does not exist.

BOOL WINAPI DllMain(
  HINSTANCE hinstDLL,
  DWORD fdwReason,
  LPVOID lpvReserved
);

Parameters

hinstDLL
[in] Handle to the DLL module. 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 calls to functions that require a module handle.
fdwReason
[in] Indicates why the DLL entry-point function is being called. This parameter can be one of the following values.
Value Meaning
DLL_PROCESS_ATTACH
1
The DLL is being loaded into the virtual address space of the current process as a result of the process starting up or as a result of a call to LoadLibrary. DLLs can use this opportunity to initialize any instance data or to use the TlsAlloc function to allocate a thread local storage (TLS) index.
DLL_THREAD_ATTACH
2
The current process is creating a new thread. When this occurs, the system calls the entry-point function of all DLLs currently 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 that a DLL's entry-point function is called with this value only by threads created after the DLL is loaded by the process. When a DLL is loaded using LoadLibrary, existing threads do not call the entry-point function of the newly loaded DLL.

DLL_THREAD_DETACH
3
A thread is exiting cleanly. If the DLL has stored a pointer to allocated memory in a TLS slot, it should use this opportunity to free the memory. The system calls the entry-point function of all currently loaded DLLs with this value. The call is made in the context of the exiting thread.
DLL_PROCESS_DETACH
0
The DLL is being unloaded from the virtual address space of the calling process as a result of unsuccessfully loading the DLL, termination of the process, or a call to FreeLibrary. The DLL can use this opportunity to call the TlsFree function to free any TLS indices allocated by using TlsAlloc and to free any thread local data.

Note that the thread that receives the DLL_PROCESS_DETACH notification is not necessarily the same thread that received the DLL_PROCESS_ATTACH notification.

lpvReserved
[in] If fdwReason is DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads and non-NULL for static loads.

If fdwReason is DLL_PROCESS_DETACH, lpvReserved is NULL if DllMain has been called by using FreeLibrary and non-NULL if DllMain has been called during process termination.

Return Values

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. (The system immediately calls your entry-point function with DLL_PROCESS_DETACH and unloads the DLL.) 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 any value other than DLL_PROCESS_ATTACH, the return value is ignored.


DllMain의 형태는

BOOL WINAPI DllMain(
  HINSTANCE hinstDLL,
DWORD fdwReason
LPVOID lpvReserved
);
이고..첫번째 인자는 현재 dll의 HINSTANCE 핸들러...어디다 사용해야할지는 아직 미지수-_-;

두번째 인자는 중요한 '왜' 호출 되었는가! 뭐, 표에 있는 내용을 보면 알겠지만 switch-case문으로 돌려서 초기화와 해제를 해주면 될 것 같다. 들어올 수 있는 내용은..

DLL_PROCESS_ATTACH
DLL_THREAD_ATTACH
DLL_THREAD_DETACH
DLL_PROCESS_DETACH

차이가 확실치는 않지만;;PROCESS는 처음으로 호출, 마지막으로 해제 될 때이고 THREAD는 이미 호출되어있는데 다른 프로세스(스레드)가 와서 덧붙여질 때 호출되는듯 하다. DLL은 카운터를 가지고 있어서 그거에 따라 공유를 감지한다고 하니 그것과도 관련이 있는 것 같다. 뭐, 일단 내가 만든 dll은 전역 변수를 사용하고 있기 때문에 다른 스레드가 와서 붙어버리면 큰일날 것이다. 그렇다면 이것을 관리하는 방법은 전역변수도 배열(vector등)로 할당해서 각 스레드 별로 인덱스를 할당해주는 방법이 있겠다. 뭐...아직 거기까지는 필요없으니 초기화만 해주자! 바로 코딩으로!


BOOL APIENTRY
DllMain(HANDLE hModule , DWORD dwReason, LPVOID lpReserved)
{
 switch(dwReason)
 {
 case DLL_PROCESS_ATTACH:
  g_nWindowSize = 10;
  break;
 case DLL_PROCESS_DETACH:
  if(g_vecPreprocess.size() > 0)
  {
   for(unsigned int loop = 0 ; loop < g_vecPreprocess.size() ; loop++)
   {
    delete g_vecPreprocess.at(loop);
   }
  }
  break;
 case DLL_THREAD_ATTACH:
  break;
 case DLL_THREAD_DETACH:
  break;
 }
 return TRUE;
}


뭐...그냥 간단하게 해봤다..어려운건 없네...컴파일만 되면 되겠군...잘 된다...
그럼 초기화가 되는지 또 확인해보자..

사용자 삽입 이미지

아까랑 똑같은 결과가 나왔다! 초기화가 제대로 작동 되는군!

해제가 제대로 되는지는....디버깅을 하고나서 메모리 릭이 발생하는지의 여부로 확인하면 될듯 하다. 이거의 확인은 귀찮으므로 나중에-_-

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함