API

DLL 에 대해서 알아보자.

디버그정 2008. 8. 4. 15:55

DLL 에 대해서 알아보자.


1.요약

Dynamic Linked Library 에 대해서 알아봅시다.


2.본문

(1) DLL의 성격

- DLL 은 필요에 따라 동적으로 로드되고 제거될 수 있으며, DLL의 하나의 인스턴스가 여러 Application 에 의해 공유되는 것도 가능하다.


(2) 장점 과 단점

- 장점

* 실행시 로드와 제거는 DLL을 사용하는 윈도우즈 App가 메모리를 효과적으로 사용한다는 것을 말한다.
* DLL에 의한 모듈화는 코드를 독립적으로 개발하고, 테스트하고 관리할 수 있도록 해준다.
* 한번에 하나 이상의 Client에 의해서 사용될 수 있기 때문에 진정으로 코드의 공유가 가능하다.
* Programming 언어 독립적일 수 있다.

- 단점

* App가 여러개의 부분으로 나뉘어지므로, App의 일부분을 잃을 수 있다.
* App의 복잡성이 증가할 수 있다. 이것은 호환성 유지에 중요한 문제가 될 수 있다.
* 같은 DLL을 여러개 가질 수 있다. 특히, 많은 사람들이 프로그램과 함께 분배하는 공통적으로 사용되고 재분배가능한 DLL을 사용할 때 문제가 발생할 수 있다.
* DLL의 치명적인 단점은 경로와 파일명에 의존한다는 것이다.

(3) DllMain

- 함수 원형

* BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID pReserved )
* 위의 pReserved 는 DLL 이 LoadLibrary() 나 FreeLibrary() 함수에 의해서 사용될 때 NULL 이다.

- dwReason 에 따른 분류

(ㄱ) DLL_PROCESS_ATTACH : 프로세스의 Startup 이나 LoadLibrary() 함수의 사용으로 DLL 이 로드되었을때
(ㄴ) DLL_PROCESS_DETACH : 프로세스의 종료나 FreeLibrary() 함수가 호출되어 DLL 이 제거되었을때, 만약 TerminateProcess() 함수로 프로세스가 종료되었을 경우에는 호출되지 않는다.
(ㄷ) DLL_THREAD_ATTACH : 새로운 Thread를 만들때 새로운 Thread의 Context 에서 수행된다. 이 부분은 주로 TLS(Thread Local Storage)의 작업을 위해서 사용한다. 특히, 이 부분은 DLL 이 로드되고 난 후의 Thread가 시작할 때만 호출된다.
(ㄹ) DLL_THREAD_DETACH : 호출한 프로세스의 Thread가 종료될 때 수행된다. 따라서 ATTACH 보다 DETACH 의 횟수가 많을 수 있다.

- DllMain 이 필요없는 경우

만약 프로세스가 DllMain()을 작성하지 않는다면, 링커는 아무것도 실행하지 않고 단지 TRUE를 리턴하는 함수를 생성한다.


(4) DLL의 함수나 클래스를 export 하는 방법

- DEF 파일 사용

프로젝트 이름과 같은 def 파일을 생성한다.


예) dll 의 이름이 "MyDll" 일 경우

LIBRARY "MyDll" 

EXPORTS 

         Func1 @1 

         Func2 @2 

위에서 '@1' 과 같이 번호를 붙이는 경우에는 반드시 다른 함수들도 번호를 붙여야 하며, 1부터 시작해야 한다.

(장점 : DLL의 공간 절약, 보다 빠른 기호 검색, DLL의 보안성 높임)
(단점 : 다른 Win32 Platform 에서 실행되지 않을 수 있다.)

- __declspec 사용

예) 아래와 같은 define 문으로 사용할 수 있다.
#ifdef IN_DLL 

#define DLL_DECL __declspec(dllexport)   // DLL 파일 

#else 

#define DLL_DECL __declspec(dllimport)   // 실행 모듈 

#endif 

* export된 함수가 별칭을 갖기 위해서는 아래와 같이 pragma를 사용할 수 있다.

#pragma comment(linker, "/export:func1=?func1@@YYAACC")

(5) 공유 Section 만들기

예) 아래와 같이 share 라는 공유 섹션을 만들 수 있다.
#pragma comment(linker, "/section:.share , RWS") 



#pragma data_seg(".share") 

long lCount = 0; 

#pragma data_seg() 

위에서 만약 lCount를 초기화 해주지 않는 다면, lCount 는 share 라는 공유 섹션이 아니라, .bss(공통적으로 존재하는 기본 Section) 라는 초기화 되지 않은 data를 관리하는 섹션안에 포함되게 된다.

(6) 기타

- 글꼴 DLL을 제외하고는 모든 리소스 전용 DLL 이 최소한 하나의 코드 segment를 가질 필요가 있으므로 여분의 DllMain(최소코드)를 가지는 것은 코드 segment를 지원하는 방법이다.


3.예제



4.참고

Beginner WindowsNT Programming 2장 DLL 부분



- 2001.08.19 Smile Seo -