Delphi의 DLL 지식 학습 5 - Delphi 응용 프로그램에서 DLL 사용
5652 단어 Delphi
은식
이 장에서 만든 첫 번째 D L L에는 인터페이스 장치가 포함되어 있습니다.다음은 DLL을 암시적으로 연결하는 인터페이스 유닛입니다.이 프로젝트의 메인 창에는 TMadk Edit 하나, TButton 하나, Tlabel 9개가 있습니다.
이 프로그램에서 사용자는 미분의 수를 입력한 다음 단추를 누르면 탭에 항목별로 결과를 표시합니다.이 결과는 PenniesLib에서 나온 것입니다.dll에서 가져온 루틴 Pennies ToCoins().
메인 창은MainFrm입니다.pas 단원에 정의된 코드
unit MainRrm;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, Mask;
type
TMainForm = class(TForm)
lblTotal: TLabel;
lblQlbl: TLabel;
lblDlbl: TLabel;
lblNlbl: TLabel;
lblPlbl: TLabel;
lblQuarters: TLabel;
lblDimes: TLabel;
lblNickels: TLabel;
lblPennies: TLabel;
btnMakeChange: TButton;
meTotalPennies: TMaskEdit;
procedure btnMakeChangeClikc(sender: TObject);
end;
var MainForm: TMainForm;
implementation
uses PenniesInt;
{R *.DFM}
procedure TMainForm.btnMakeChangeClick(Sender: TObject);
var
CoinsRec: TCoinsRec;
TotPennies: word;
begin
{call the DLL function to determine the minimum coins required
for the amount of pennies specified}
TotPennies:= PenniesToCoins(StrToInt(meTotalPennies.Text), @CoinsRec);
with CoinsRec do
begin
{Now display the coin information}
lblQuarters.Caption:= IntToStr(Quarters);
lblDimes.Caption:= IntToStr(Dimes);
lblNickels.Caption:= IntToStr(Nickels);
lblPennies.Caption:= IntToStr(Pennies);
end;
end;
end.
MainFrm에 주의하세요.pas는 인터페이스 장치 PenniesInt를 사용합니다.PenniesInt.pas에는 PenniesLib이 포함됩니다.dpr의 함수에 대한 외부 설명입니다.Win 32 시스템은 응용 프로그램이 실행될 때 자동으로 Pennies Lin으로 이동합니다.dll, 이 프로그램의 프로세스 주소 공간에 비추기
import 인터페이스 단원은 Pennies Int 단원을 사용하지 않고MainFrm에서 선택할 수 있습니다.pas의 implementation 부분은 PenniesToCoins() 함수를 외부에서 설명하면 됩니다. 코드는 다음과 같습니다.
implementation
function PenniesToCoins(TotPennies: word; ChangeRec: PChangeRec): Word; stdcall; external 'PENNIESLIB.DLL';
하지만 MainFrm에서.pas는 PChangeRec와 TchangeRec를 다시 정의해야 합니다. 그렇지 않으면 컴파일 명령인 PENIESLIB를 사용하여 프로그램을 컴파일할 수도 있습니다.이 기술은 DLL의 일부 루틴에 액세스하기만 하면 적절합니다.그러나 대부분의 경우 DLL에 접근해야 할 뿐만 아니라 DLL에 정의된 데이터 형식도 인용해야 하기 때문에 인터페이스 단원을 사용하는 것이 가장 좋다
주의: 어떤 때는 다른 소프트웨어 업체의 DLL을 호출해야 하는데, 이때는Pascal의 인터페이스 단원이 없을 수도 있지만, C/C++의 도입 라이브러리가 있을 수도 있습니다.만약 그렇다면, 이 라이브러리를 같은 효과의 Pascal 인터페이스 단원으로 현시하기만 하면 됩니다.
2. 현식 호출
비록 스텔스 호출은 매우 편리하지만, 가장 이상적인 방법은 아니다.만약 여러 개의 루틴을 포함하는 DLL이 있다면, 이 루틴들은 쓸모가 없을 수도 있다. 그러면, 이 DLL로 가져오는 것은 메모리를 낭비하는 것이 분명하다.특히 하나의 애플리케이션에 여러 개의 DLL을 사용해야 하는 경우에는 이러한 비용이 낭비됩니다.또 다른 상황은 여러 버전의 표준 함수인 프린터 드라이버 한 세트가 각각 여러 개의 DLL로 이루어진다는 것이다.이 경우 필요한 버전의 DLL을 호출하는 것이 가장 좋습니다.이런 방식은 바로 호출을 표시하는 것이다.
unit MainFrm;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
type
TShowCalendar = function(AHandle: THandle; ACaption: String): TDateTime; Stdcall;
EDLLLoadError = class(Exception);
TMainForm = class(TForm)
lblDate: TLabel;
btnGetCalendar: TButton;
procedure btnGetCalendarClick(Sender: TOnject);
end;
var
MainForm: TMainForm;
implementation
{$R *.DFM}
procedure TMainForm.btnGetCalendarClick(Sender: TObject);
var
LibHandle: THandle; //!!!!!
ShowCalendar: TShowCalendar; //!!!!!!
begin
LibHandle:= LoadLibrary('CALENDARLIB.DLL'); //!!!!!!
try
if LibHandle = 0 then
raise EDLLLoadError.Create('Unable to load DLL');
@ShowCalendar:= GetProcAddress(LibHandle, 'ShowCalendar');
if not(@ShowCalendar = nil) then
lblData.Caption:= DateToStr(ShowCalendar(Application.Handle, Caption))
else
RaiseLastWin32Error;
finally
FreeLibrary(LibHandle);
end;
end;
end.
위의 단원은 먼저 프로세스 데이터 형식인 TShow Calendar를 정의했는데 이 유형은Calendar Lib입니다.dll의 함수 형식입니다.이어 호출이 실패할 때 이 이상을 일으킬 수 있는 특수한 이상류를 성명했다.btnGetCalendarClick () 이벤트 처리 과정에서 세 개의 Win32 API 함수를 사용했습니다: LoadLibrary (), FreeLibrary (), GetProcAddress ().
LoadLibrary() 선언은 다음과 같습니다.
function LoadLibrary(lpLibFileName: PChar): HMODULE; stdcall;
위 함수는 lpLibFileName 매개 변수로 지정된 DLL 모듈로 가져와 호출 프로세스의 주소 공간에 매핑합니다.호출에 성공하면 함수는 이 모듈의 핸들을 되돌려줍니다.실패하면 0 값을 되돌려주고 이상을 일으킵니다.온라인 도움말에서 LoadLibrry () 함수에 대한 상세한 설명과 되돌아올 수 있는 오류 값을 볼 수 있습니다
FreeLibrary() 선언은 다음과 같습니다.
function FreeLibrary(hLibModule: HMODULE): BOOl; stdcall;
FreeLibrary() 함수는 LibModule에서 지정한 라이브러리의 인스턴스 수를 줄입니다.이 DLL의 인스턴스 수가 0일 경우 호출된 DLL이 해제됩니다.인스턴스 수 이 DLL을 사용한 작업 수를 기록합니다.
GetProcAddress()는 이렇게 정의됩니다.
function GetProcAddress(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
GetProcAddress () 는 함수가 모듈에 있는 주소를 되돌려줍니다. 이 주소는 hModule 파라미터가 모듈을 지정합니다.hModule은 LoadLibrary() 함수에서 반환된 결과 THandle입니다.GetProcAddress() 호출이 실패하면 nil로 돌아갑니다.자세한 오류 정보는 GetLastError () 를 호출해야만 얻을 수 있습니다.
Button1의 OnClick 이벤트 처리 프로세스에서 먼저 LoadLibrary()를 호출하여 CALDLL을 호출합니다.실패할 경우 예외가 발생합니다.성공하면 GetProcAddress()를 호출하여 함수 ShowCalendar()의 주소를 가져옵니다.변수 ShowCalendar 앞에 주소 지정 연산자@를 추가하면 컴파일할 때 유형 변환 오류가 발생하지 않습니다.함수 Show Calendar () 의 주소를 얻으면 TShow Calendar가 정의한 대로 사용할 수 있습니다.마지막으로 사용하지 않을 때finally 블록에서 FreeLibrary () 를 호출해서 풀어야 합니다.
이 함수를 호출할 때마다 DLL을 불러올 뿐만 아니라 풀어야 한다는 것을 알 수 있을 것이다.만약 응용 프로그램이 실행될 때 한 번만 호출하면 현식 호출의 장점이 뚜렷하고 메모리의 소모를 효과적으로 줄일 수 있다.그러나 이 함수가 빈번하게 호출되려면 빈번하게 호출되고 방출되면 시스템의 부담이 커진다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[Delphi] TStringBuilder그리고 꼭 사용해야만 할까? 그림처럼 Heap 영역에 "Hello" 공간을 생성하고 포인팅을 한다. "Hello World" 공간을 새로 생성한 후 포인팅을 하게 된다. 결국 "Hello" 라는 String 객체가 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.