상세 컨텐츠

본문 제목

DllMain 정리

똑똑한 개발/C++

by 성댕쓰 2022. 8. 24. 15:13

본문

DllMain

Dynamic link library로 링크할 경우, DllMain이 진입점 함수로 불린다.

기본 함수 모양은 다음과 같다.
함수 이름은 대소문자 구별하므로 주의하자.

BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpvReserved )  // 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:
        
            if (lpvReserved != nullptr)
            {
                break; // do not do cleanup if process termination scenario
            }
            
         // Perform any necessary cleanup.
            break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

DllMain은 프로세스 시작이나 쓰레드 시작할 때 호출된다.
fdwReason에 각 상황에 따라 다음 4가지 중 하나의 값으로 들어온다.

  • DLL_ATTACH_PROCESS
  • DLL_DETACH_PROCESS
  • DLL_ATTACH_THREAD
  • DLL_DETACH_THREAD

lpReserved는 DLL_PROCESS_ATTACH인 경우,

  • Dll이 명시적 런타임 링크 방식으로 로드 되면 NULL
  • 암시적 로드타임 링크 방식이면 not NULL

값을 갖는다.

DLL_PROCESS_DETACH인 경우,

  • FreeLibrary 호출 또는 Dll 로드 실패이면 NULL
  • 프로세스가 종료중이라면 not NULL

값을 갖는다.

주의사항

DllMain이 호출되었을 때 다른 Dll은 로드되지 않았거나, DllMain이 호출되지 않았을 수도 있다.
따라서, DllMain에서 다른 dll의 함수를 호출하면 안된다.
또한 Dll 의존 루프가 발생할 수도 있어서, LoadLibrary, FreeLibrary도 호출해선 안된다.

DllMain 함수를 만들지 않으면 C/C++ 런타임 라이브러리 DllMain 함수가 사용된다.

DllMain의 네 가지 통지

  1. DLL_PROCESS_ATTACH

2. DLL_PROCESS_DETACH

  1. 프로세스 종료
    • 특정 쓰레드가 TerminateProcess 함수 호출하여 프로세스 종료하면,
      다른 DllMain 호출하지 않음.

    2. FreeLibrary 호출


3. DLL_THREAD_ATTACH
프로세스 내에 새로운 쓰레드가 생성되면,
시스템은 프로세스에 로드된 모든 dll의 DllMain함수를
DLL_THRAD_ATTACH값을 전달하여 호출한다.
하지만 쓰레드가 먼저 생성되고 Dll이 로드 되었다면 호출되지 않는다.
또, DLL_PROCESS_ATTACH를 호출한 쓰레드에 대해선 호출하지 않는다.

4. DLL_THREAD_DETACH
시스템은 ExitThread를 호출할 때 스레드를 바로 죽이지 않고
프로세스 주소 공간에 매핑된 모든 dll의 DLL_THREAD_DETACH 값을 인자로 하여 호출하고
모든 Dll이 DllMain함수를 반환하면 그 때 쓰레드를 종료한다.
만약, 특정 스레드가 TerminateThread 함수를 호출하여 스레드를 종료한 경우
DLL_THREAD_DETACH 값으로 어떤 DllMain 함수도 호출되지 않는다.

참고 :
https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain?redirectedfrom=MSDN
http://egloos.zum.com/sweeper/v/2991972

'똑똑한 개발 > C++' 카테고리의 다른 글

Strand 정리  (0) 2022.08.23
[boost] asio#2  (0) 2022.05.02
[boost] asio #1  (0) 2022.05.01
[Visual Studio] Character Set Unicode vs MBCS  (0) 2022.04.26
enable_shared_from_this  (0) 2022.04.22

관련글 더보기

댓글 영역