DLL(Dynamic-link library)란 (4)
DLL의 procedure나 function을 어디에서 import할 것인가?
물론, 그것을 사용하 는 unit 내에서 import할 수도 있다.
하지만 대부분의 경우, 개별 unit을 구성하고
그곳에 한 DLL내의 procedure나 function을 import하기 위한
코드를 모두 몰 아넣는 것이 일반적이다.
이렇게 DLL의 import를 목적으로 구성된 unit이 Import Unit이다.
import unit의 좋은 예는 '{DELPHI}\Source\RTL\Win' 내의 unit들이다.
이것들은 모두 Windows API를 지원하기 위해
각 DLL별로 만들어진 모든 unit 의 소스가 있다.
이 unit들, 특히 Windows.pas를 자세히 살펴보면
델파이에서 DLL을 어떻게 사용하는지,
C의 공용체(union)을 델파이에서는 어떻게 구현하는지 등을 상세히 알 수 있다.
이렇게 import unit을 이용하는 이유는 DLL별로 unit을 구성하여 보다
정리된 형태로 DLL들을 사용하게 하기 위해서이다.
또한 project 에 포함하여 컴파일하는 것으로
각 프로젝트마다 DLL의 사용을 위한 코드를 넣는
수고를 하지 않아도 된다는 장점이 있다.
Import unit에 들어가는 내용은 단지 선언들이다.
하지만 이것 역시 .DCU를 구성하고 프로젝트의 일부가 될 수 있다.
C에서는 이것을 헤더파일(*.h)로 관리한다.
하나의 예를 살펴보자.
아래는 날짜와 시간을 설정하기 위해 DLL 내부에서
사용 하는 구조체(델파이에서는 record)와
procedure, function등을 선언한 import unit이다.
unit DateTime;
interface
type
TTimeRec = record Second: Integer;
Minute: Integer;
Hour: Integer;
end;
type
TDateRec = record Day: Integer;
Month: Integer;
Year: Integer;
end;
procedure SetTime(var Time: TTimeRec);
procedure GetTime(var Time: TTimeRec);
procedure SetDate(var Date: TDateRec);
procedure GetDate(var Date: TDateRec);
implementation
procedure SetTime; external 'DATETIME' index 1;
procedure GetTime; external 'DATETIME' index 2;
procedure SetDate; external 'DATETIME' index 3;
procedure GetDate; external 'DATETIME' index 4;
end.
단지, uses문에 DateTime을 추가하는 것만으로도
어느 프로젝트에나 DATETIME.DLL을 사용할 수 있다.
이 import unit을 이용한 프로그램의 예는 아래 와 같다.
program ShowTime;
{ $APPTYPE CONSOLE }
uses DateTime;
var
Time: TTimeRec;
begin
GetTime(Time);
with Time do
WriteLn('The time is ', Hour, ':', Minute, ':', Second);
end.
이것은 또한 DATETIME.DLL이 변경되는 상황에서도
DateTime unit 하나만 바꾸어 주면 된다는 이점도 있다.
Static import와 dynamic import import에는 두가지 종류가 있다.
static import는 DLL의 진입점(Entry Point)가 항상 고정이다.
따라서 언제나 동일한 procedure나 function이 호출된다.
반면 dynamic import는 DLL의 이름이나 인덱스 번호가 런타임에서 지정된다.
static import는 우리가 일반적으로 사용하는 형태이고
'Import Unit'절에서 다룬 코드 가 그 예가 된다.
dynamic import의 예는 다음과 같다.
DATETIME.DLL의 GetTime procedure를 호출 하는
ShowTime 프로그램의 예이다. 여기서 GetTime이라는 procedure형
변수가 DLL내의 GetTime procedure 주소를 가져오는데
이용된다는 것에 유의하자.
program ShowTime;
uses Windows;
type
TTimeRec = record
Second: Integer;
Minute: Integer;
Hour: Integer;
end;
TGetTime = procedure(var Time: TTimeRec);
var
Time: TTimeRec;
Handle: THandle;
GetTime: TGetTime; // procedure형의 변수
begin
Handle := LoadLibrary('DATETIME.DLL'); // DLL의 로딩과 핸들얻기
if Handle <> 0 then begin
@GetTime := GetProcAddress(Handle, 'GetTime'); // DLL의 GetTime의 주소읽 기
if @GetTime <> nil then begin
GetTime(Time); // DLL의 GetTime 호출 with Time do
WriteLn('The time is ', Hour, ':', Minute, ':', Second); end;
FreeLibrary(Handle); end;
end;
위에서 LoadLibrary와 FreeLibrary, GetProcAddress는
Windows API로 uses절에 Windows를 추가함으로써 사용할 수 있다.
이중 GetProcAddress는 LoadLibrary에 서 얻은 DLL 핸들을 이용해
특정 Method의 주소를 알아내는 function이다.
이해 하기 어렵지 않은 코드이다.
5편계속...
'Delphi Tip > 파일' 카테고리의 다른 글
DLL만들기와 사용방법 (0) | 2023.06.28 |
---|---|
DLL(Dynamic-link library)란 (5) (0) | 2023.06.27 |
DLL(Dynamic-link library)란 (3) (0) | 2023.06.23 |
DLL(Dynamic-link library)란 (2) (0) | 2023.06.22 |
DLL(Dynamic-link library)란 (1) (0) | 2023.06.21 |
댓글