MFC :: Chapter 11 (동적 연결 라이브러리 DLL) - 105번째 이야기
동적 연결 라이브러리 DLL이란 Dynamic Link Library의 약자이다. 동적 연결 라이브러리란 프로그램 내부에 라이브러리가 있는 것이 아니라 외부에 따로 독립적으로 실행 가능한 파일로 설정되어 있어 필요시 로드할 수 있는 라이브러리를 말한다. DLL은 프로그램을 작성할 때 각 모듈별로 나누어서 프로그램을 작성하는 것이 가능하다. 그로 인해 유지보수가 용이하고 여러 사람이 나누어서 프로그램을 만들 수 있다. 자주 쓰는 모듈 같은 경우 DLL로 제작하여두면 프로그램의 재사용과 프로그램 크기 또한 줄일 수 있다. Windows에서는 기본적으로 많이 쓰는 DLL을 윈도우 자체적으로 설치해 OS 자체나 다른 프로그램들이 사용하게 하고 있다.
DLL의 링크
DLL을 링크하는 방법은 Implicit 링킹과 Explicit 링킹의 두 가지 방법이 있다. Implicit 링킹은 프로그램이 시작되면서 해당 DLL을 바로 로드하는 방법으로 DLL을 만들고 난 후 세 가지 파일을 이용하여 메인 프로그램을 작성하는 반면에 Explicit 링킹은 세 가지 파일이 필요 없이 단순하게 DLL을 이용하여 로드할 수 있는 방법을 의미한다.
1) Implicit 링킹
Implicit 링킹은 프로그램이 시작되면서 해당 DLL을 바로 로드하는 방법이다. 이때 필요한 파일은 DLL 파일과 LIB 파일과 .H의 확장자를 가진 헤더파일이다. DLL 파일은 함수명만 가지고 있으며 필요한 인자 값은 가지고 있지 않다. 이런 인자를 맞춰주기 위하여 DLL 파일과 함께 헤더 파일과 LIB 파일이 필요하다. 이러한 인자 설정은 헤더 파일(.H 파일)에서 해주게 된다. 메인 프로그램을 컴파일 할 때 DLL을 컴파일 하지는 않고 실행 시에만 DLL 파일에 접근하기 때문에 컴파일 에러가 난다. 그 이유는 DLL 안에 있는 함수들은 메인 프로그램에 있는 어느 것과도 링크되어 있지 않기 때문이다. 이것을 방지하기 위하여 LIB 파일 안에는 아무런 기능도 하지 않는 가상적인 함수를 만들어 주어 컴파일 시에는 이 함수로 컴파일을 하게 된다.
2) Explicit 링킹
Explicit 링킹은 단순히 DLL과 LIB만을 가지고 로드를 한다. Explicit 링킹으로 DLL을 로드할 경우 세 가지 함수를 이용한다. 이 세 가지 함수는 DLL을 로드할 때 사용하는 LoadLibrary() 함수, 함수의 포인트를 찾을 때 사용하는 GetProcAddress() 함수, 라이브러리를 해제할 때 사용하는 FreeLibrary() 함수이다. 세 가지 함수의 사용법은 다음과 같다.
1. LoadLibrary() 함수는 DLL을 로드할 때 사용하는 함수이다.
a. 이 함수의 원형은 다음과 같다.
HINSTANCE LoadLibrary(LPCTSTR lpLibFileName);
( lpLibFileName : 로드하고자 하는 DLL 파일명 )
b. 이 함수로 DLL을 로드하는 사용법은 다음과 같다.
HINSTANCE hDll;
hDll = LoadLibrary("Practice11_1DLL.dll");
2. GetProcAddress() 함수는 필요한 함수의 포인터를 찾을 때 사용하는 함수이다. LoadLibrary() 함수를 이용하여 DLL을 로드하면 인스턴스 핸들을 반환한다. 이 인스턴스 핸들을 이용하여 필요한 함수의 포인터를 찾는다.
a. 이 함수의 원형은 다음과 같다.
FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName);
( hModule : DLL의 인스턴스 핸들
lpProcName : DLL안에 있는 함수 이름 )
b. 이 함수로 로드된 DLL 함수의 주소를 받아오는 사용법은 아래와 같다.
typedef int(*CalenderFunc) (int num);
CalenderFunc lpCalenderFunc;
lpCalenderFunc = (CalenderFunc)GetProcAddress(hDll,"Calender");
lpCalenderFunc()을 실행하는 것은 DLL의 Calender() 함수를 실행하는 것과 같다.
3. FreeLibrary() 함수는 라이브러리에서 함수를 실행한 후 DLL의 사용을 종료할 때 사용하는 함수이다. 만약 이때 다른 프로그램에서 해당 DLL을 사용할 경우 DLL은 메모리에서 사라지지 않고 다른 프로그램을 위하여 존재한다.
a. 이 함수의 원형은 다음과 같다.
BOOL FreeLibrary(HMODULE hLibModule);
( hLibModule : 로드된 DLL의 핸들 )
b. 이 함수로 로드된 DLL을 종료하는 사용법은 아래와 같다.
FreeLibrary(hDll);
DLL의 종류
DLL의 종류에는 정규 DLL과 확장 DLL 두 가지가 있다. 정규 DLL이란 Win32 프로그램으로 설정되어 MFC를 사용하지 않은 다른 프로그램과도 원활히 연결할 수 있는 DLL이고 확장 DLL은 MFC 전용 DLL을 의미한다.
1) 정규 DLL
정규 DLL은 Win32 프로그래밍 환경에서 만든다. 즉 클래스 형태가 아닌 C 함수 형태로 DLL을 제작하기 때문에 정규 DLL은 MFC를 사용하지 않은 다른 프로그램에서도 사용할 수 있다. 하지만 내부적으로는 클래스를 사용할 수 있다. 정규 DLL이 MFC 라이브러리를 사용할 경우 라이브러리를 공유하거나 아니면 자체적으로 모두 가지고 있거나 둘 중 하나를 선택할 수 있다.
● 정규 DLL 작성법
1. void Calender()라는 함수를 DLL로 만들려고 할 경우 선언시 함수 앞에 다음과 같이 설정 하여야 한다. 이렇게 설정하면 현재 함수는 DLL 외부에서 호출하여 사용할 수 있는 함수가 된다.
extern "C"_declspec(dllexport) void Calender();
2. 위와 같이 선언한 후 함수 앞에 _declspec(dllexport)를 쓰고 함수를 만들어 함수 내용을 코딩하면 된다.
_declspec(dllexport) void Calender()
{
// 함수 본체
}
3, 이렇게 한 후 컴파일하면 DLL 파일과 LIB 파일이 생성된다.
● 정규 DLL 사용법
1. void Calender()라는 함수를 호출하려면 선언시 함수 앞에 다음과 같이 설정하여야 한다. 선언할 때 함수명과 같아야 하고 단 dllexport를 dllimport로 바꾸어 주면 된다.
extern "C"_declspec(dllimport) void Calender();
2. 위와 같이 선언한 후 [Project] 메뉴에서 [Setting]을 선택하고 프로퍼티 시트에서 [Link]탭을 선택한 후 다음과 같이 DLL을 작성할 때 만들어진 LIB를 설정해준다. 이 때 파일은 전체 경로를 설정하든가 프로젝트 디렉토리에 해당 DLL의 LIB 파일이 있어야 한다.
3. DLL의 함수를 호출하여 사용하면 된다.
1) 확장 DLL
확장 DLL은 C++로 DLL을 만들 수 있는 MFC 전용 DLL이다. 즉 클래스를 라이브러리로 사용하고 호출할 수 있는 형태로 제작된 DLL이다. 메인 프로그램에서 DLL을 호출할 때 클래스로서 호출할 수 있고 MFC 구조체와 원활하게 연결될 수 있는 구조체로 되어있다. 쉽게 말하면 그냥 클래스 사용하듯이 사용하면 된다. DLL이 MFC에서만 사용한다면 이 방법으로 DLL을 작성하여 사용하는 것이 좋다.
● 확장 DLL 작성법
1. 확장 DLL은 클래스명 선언 앞에 단순히 AFX_EXT_CLASS를 설정한다.
class AFX_EXT_CLASS CCalenderDlg::Public CDialog
2. 이렇게 한 후 컴파일하면 DLL 파일과 LIB 파일이 생성된다.
● 확장 DLL 사용법
1. Implicit 링킹을 이용하여 LIB 파일을 링크시킨다.
2. DLL 클래스 헤더 파일을 포함시킨다.
3. 일반적인 클래스 사용하듯이 확장 DLL 클래스를 사용하면 된다.
트랙백 주소 :: http://jhbae.net/trackback/105
-
Subject: [dll] 정규식 DLL 만들고 사용하기
Tracked from 어퓨굿맨 2008/02/28 14:09 삭제정규 DLL : 윈도우가 생겼을 때 부터 만들어 왔던, 기본적인 DLL.함수만을 export 할 수 있다. 이것을 확장한 것을 "확장DLL" 이라고 하는데, 이것은 Class도 export 할 수 있다. 1. DLL 만들기1) 함수 원형을 정의한다.extern "C" __declspec(dllexport) int sam(int n); -알고 넘어가기-"C"는 함수 naming을 C++이 아닌 C를 따르겠다는 뜻이고__declspec은 import할...



Practice11_1.rar
댓글을 달아 주세요.
정말 잘 보고 갑니다. 오랜만에 하면 자꾸 헷갈리는데 명쾌히 설명해 주셨네요. // 121.159.55.***
교재에 있는 것을 타이핑 한 것 밖에 ^^;
도움이 되셨다니 다행입니다 :-) // 121.140.62.***