컴퓨터 공부/Win32 API 프로그래밍

[5월 12일 1교시] DLL

려리군 2009. 5. 12. 15:30

동적링크

실행 중에 라이브러리에 있는 함수를 호출

실행 파일의 크기가 작아짐.

DLL 파일 필요


장점

한 코드를 여러 프로그램이 사용

프로그램 크기가 작아짐

리소스 교체 가능

디버깅 용이

혼합 프로그래밍(Basic등) 가능


단점

DLL없으면 실행 불가능

버전이 교체되었을 경우 기존 프로그램 실행이 안될 수 있음.


관리

클라이언트 프로그램들이 DLL코드를 공유.

DLL 로드 카운트를 두어 0이 되면 메모리에서 삭제.


접속

Export : DLL이 제공하고자 하는 함수 정보를 공개한다.

Import : 실행파일(클라이언트)가 DLL의 어떤 함수를 사용하겠다고 선언한다.


__declspec : Storage Class 정의

thread : 해당 쓰레드에서만 사용할 수 있는 변수.

naked : 가상 디바이스 드라이버를 작성할 때 사용.

dllimport : 실행파일에서 import(implicit방식에서 사용)

예시) extern "C" __declspec(dllimport) int AddInteger(int a, int b);        // c, cpp파일

dllexport : DLL파일에서 export

예시) extern "C" __declspec(dllexport) int AddInteger(int a, int b){ ... } // DLL파일


extern "C"

함수를 외부로 공개할 때 C 스타일로 공개(혼합 프로그래밍(MFC, Basic등에서 사용) 가능)

C++은 함수 overloading을 허용하기 때문에 다른 언어에서 사용 불가.


연결방식

묵시적 연결 : 함수가 어느 DLL에 있는지 밝히지 않고 DLL파일이 있다고 생각하고 사용. Load Time Linking

명시적 연결 : 어느 DLL에 있는 함수인지 밝히고 사용. Run Time Linking


명시적 연결

HMODULE WINAPI LoadLibrary(__in  LPCTSTR lpFileName);

참고주소 : http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx

호출한 프로세스의 주소 공간에 특정 모듈을 불러온다. 특정 모듈은 다른 모듈들을 불러올 수 있는 원인이 된다. 주로 DLL을 불러오는 경우로 사용.

리턴 : 성공시 모듈의 핸들. 실패시 NULL

lpFileName : 모듈의 이름. 라이브러리나 실행 파일의 이름이 될 수 있다.


FARPROC WINAPI GetProcAddress(__in  HMODULE hModule, __in  LPCSTR lpProcName);

참고주소 : http://msdn.microsoft.com/en-us/library/ms683212(VS.85).aspx

특정 DLL로부터 export된 함수나 변수의 주소를 얻는다.

리턴 : 성공시 DLL의 함수나 변수의 포인터, 실패시 NULL

hModule : 함수나 변수를 포함하고 있는 DLL 모듈의 핸들. LoadLibrary, LoadLibraryEx, GetModuleName 함수는 이 핸들을 리턴한다. LOAD_LIBRARY_AS_DATAFILE플래스를 사용하지 않은 핸들이어야 한다.

lpProcName 

변수나 함수 이름. 

혹은 함수의 ordinal value(함수에 대응되는 숫자값. DEF파일로 정의 가능)

참고주소 : http://msdn.microsoft.com/en-us/library/d91k01sh(VS.80).aspx


BOOL WINAPI FreeLibrary(__in  HMODULE hModule);

참고주소 : http://msdn.microsoft.com/en-us/library/ms683152(VS.85).aspx

불러온 DLL 모듈을 해제하고 필요하다면 참조 카운트를 하나 줄인다. 만약 참조 카운트가 0이면 모듈은 호출한 프로세스의 주소공간으로부터 해제하고 핸들은 더 이상 유효하지 않게 된다.

리턴 : 성공시 TRUE, 실패시 FALSE

hModule : 불러온 라이브러리 모듈의 핸들. LoadLibrary, LoadLibraryEx, GetModuleHandle, GetModuleHandleEx 함수는 이 핸들을 리턴한다.


Dll시작함수

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

참고주소 : http://msdn.microsoft.com/en-us/library/ms682583(VS.85).aspx

DLL로 진입하는 지점. 시스템은 프로세스나 쓰레드를 시작하고 끝낼 때, 프로세스의 첫번째 쓰레드를 사용하는 DLL이 각각 불러오기 위해 진입 지점 함수를 호출한다. 시스템은 LoadLibrary와 FreeLibrary 함수를 사용할 때 DLL을 위한 진입 지점 함수를 호출한다.

hinstDLL : DLL 모듈의 핸들. 이 값은 DLL의 시작 주소이다. DLL의 인스턴스 핸들(HINSTANCE)은 DLL의 모듈 핸들(HMODULE)과 같다. 

fdwReason

 - DLL_PROCESS_ATTACH : 프로세스의 주소공간에 맵핑 될 때 호출. LoadLibrary등.

 - DLL_PROCESS_DETACH : 프로세스의 주소 공간에서 불리될 때 호출. FreeLibrary 등.

 - DLL_THREAD_ATTACH : 쓰레드를 생성할 때마다 호출. 쓰레드 별로 초기화를 수행할 때 사용한다.

 - DLL_THREAD_DETACH : 쓰레드가 종료할 때마다 호출.

lpvReserved

 - DLL_PROCESS_ATTACH면 동적 불러오기를 위해서는 NULL, 정적 불러오기면 NULL이 아니다.

 - DLL_PROCESS_DETACH면 FreeLibrary에 대해서는 NULL, 프로세스가 종료중이면 NULL이 아니다.

리턴값

 DLL_ATTACH일 때 TRUE를 리턴하면 초기화 성공. 그렇지 않으면 FALSE를 사용하며 LoadLibrary에 NULL이 리턴될 것이다.