동적 링크 라이브러리에 대해서 서칭을 하다가 dll 진입점 함수에 대해서 설명이 있어서
포스팅 합니다. 제목이 "DLL 만들기"이지만 "DLL 진입점 함수 : DllMain" 이라고 한게 나을듯 하네요.
그리고 DLL은 콘솔로 만들어도 상관없습니다.
추가적으로 Microsoft에서 제공하는 MSDN에 기재된 DLL 링크 입니다.
MSDN:DLL 링크 : http://msdn.microsoft.com/ko-kr/library/1ez7dh12(VS.90).aspx
IDE : Visual Studio 2008
파일 - 새로만들기- 프로젝트 => 프로젝트 형식 - Win32 - Win32 프로젝트
=> Win32 응용 프로그램 마법사 - 응용 프로그램 종류 : DLL 선택
-> DLL내에서 함수를 구현 할 때 16bit 형식으로 DEF(모듈 정의 파일)을 만들어 링커 스위치로 사용하는 방법이 있고, 32bit 형식으로 __declspec (export) 선언문을 사용하는 방법 2가지가 존재한다. DEF를 사용하면 서수를 지정(명시적 로딩시 함수명으로 로드하는 것 보다 빠름), 사용할 함수명 변경(서로 다른 DLL에서 같은 이름의 함수 존재시 각각 다른 이름으로 충돌없이 사용가능) 외 다수 장점이 있고, __declspec (export) 선언문을 사용하면 컴포넌트 형식(클래스도 익스포트 가능해진다...)으로 사용 가능한 각각의 장점이 있다. 하지만 최근 __declspec (export) 선언문을 사용하는 것이 추세이다. 이 두 가지 방법 중 하나라도 하지 않으면 LIB 파일이 생성되지 않고 익스포트 정보도 생성되지 않기 때문에 두 방법 중 한가지는 꼭 사용해야 한다.
; DLL의 엔트리 포인트(Entry Point, 진입점)로 DLL 전체(프로세스 및 스레드)의 초기화와 종료 처리를 담당(해당 시기에 맞게 개발자가 정의)한다. 만약 해당 DLL 제작시 C계열의 프로그램에서만 활용한다고 보장만 된다면 DllMain()은 생략해도 무관하다. 그 이유는 C 런타임 라이브러리와 링크 할 경우 C 런타임이 엔트리 포인트를 자동으로 제공해주기 때문이다. 뭐 쉽게 다시 말하면 자동으로 디폴트 DllMain() 함수를 만들어 준다. ㅡㅡ;;;
= Return Value(BOOL) : 보통 성공적으로 수행하면 TRUE를 반환 시키면된다. 만약 문제가 생길 경우 FALSE를 반환 시키면 되는데, FALSE 반환시 해당 DLL을 호출한 프로그램이 종료된다.
- 사용 예> //사용할 함수 정의
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID lpRes)
{
//변수 선언 및 필요 기능 구현
switch(fdwReason)
{
case DLL_PROCESS_ATTACH: //switch문 대신 if
fdwReason==DLL_...) 해도 됨
//기능 구현
break;
case DLL_PROCESS_DETACH:
//기능 구현
break;
case DLL_THREAD_ATTACH:
//기능 구현
break;
case DLL_THREAD_DETACH:
//기능 구현
break;
}
return TRUE;
}
*fdwReason 메시지 - DLL_PROCESS_ATTACH : DLL이 프로세스(즉, 메인 스레드)의 주소 공간에 맵핑될 경우 호출된다. 주로 메모리를 할당하거나 시스템 전역 핸들을 초기화하는 용도로 사용된다. 암시적 호출일 경우 프로세스가 시작될 때, 명시적 호출 일 경우 LoadLibrary()가 리턴되기 전에 이 값과 같이 DllMain()이 호출된다.
- DLL_PROCESS_DETACH : DLL이 프로세스의 주소 공간에서 분리될 때 호출된다. 주로 DLL_PROCESS_ATTACH에서 할당된 메모리 해제나 시스템 전역 핸들을 제거하는 용도로 사용된다. 암시적 호출일 경우 프로세스가 종료될 때, 명시적 호출일 경우 FreeLibrary() 함수가 호출된 경우 이 값과 DllMain()이 호출된다.
- DLL_THREAD_ATTACH : DLL을 사용하는 클라이언트 프로세스에서 스레드를 생성할 때마다 이 값과 함께 DllMain() 함수가 호출된다. DLL에서는 이 메시지를 받았을 경우 스레드 별 초기화를 수행해야한다. 그리고 이미 존재하는 스레드에 대해서는 전달되지 않으며 스레드가 새로 생성될 때만 전달된다. 최상위 스레드(즉, 메인 스레드)는 DLL_PROCESS_ATTACH에서 처리되므로 이 메시지가 발생하지 않는다.
- DLL_THREAD_DETACH
: DLL을 사용하는 클라이언트 프로세스에서 스레드가 종료될 때마다 이 값과 함께 DllMain() 함수가 호출된다. DLL에서는 이 값을 받았을 때 스레드 별로 종료 처리를 수행한다. DLL 로드 전 존재했던 스레드는 DLL_THREAD_ATTACH 메시지 처리가 되지 않았을 것이기 때문에 해제해야 할 경우 초기화가 된 것인지 확인 한 후 해제 할 것만 처리한다.