Delphi DLL 생성, 정적 및 동적 호출
제1장 DLL 소개
현재 학습 과정에서 DLL 파일을 사용해야 하기 때문에 배웠습니다. 여기서 총결산을 하겠습니다.
먼저 DLL에 대해 간략하게 설명합니다.
1, 실행 파일 크기 감소
DLL 기술의 상당 부분은 실행 가능한 파일의 크기를 줄이기 위한 것이다.운영 체제가 Windows 시대에 접어들면서 그 크기는 이미 수십 메가바이트에서 몇 백 메가바이트에 이르렀다.DOS 시대의 단일 실행 파일 시스템을 사용한다면 실행 가능한 파일의 크기가 수십 메가에 달할 수 있다는 것은 모두가 받아들일 수 없는 일이다.해결 방법은 동적 링크 기술을 이용하여 큰 실행 가능한 파일을 많은 작은 실행 가능한 프로그램으로 분할하는 것이다.
2, 자원 공유 실현
여기서 가리키는 자원 공유는 여러 가지 측면을 포함하는데 가장 많은 것은 메모리 공유, 코드 공유 등이다.DLL의 또 다른 두드러진 특징은 메모리에 한 번만 불러오는 것이다. 이 점은 유한한 메모리를 절약할 수 있을 뿐만 아니라 여러 프로세스에 동시에 서비스를 제공할 수 있다.
3, 간편한 유지 관리 및 업그레이드
소프트웨어 실행에 문제가 발생할 경우 프로그램을 다시 설치할 필요가 없으며 해당 DLL 파일만 교체하면 됩니다.
4, 비교적 안전
여기서 말하는 안전도 여러 방면을 포함한다.예를 들어 DLL 파일이 바이러스에 노출될 확률이 일반적인 EXE 파일보다 훨씬 낮다.또한 동적 링크이기 때문에 파괴 작업에 종사하는 일부'고수'들에게 다소 반집성의 어려움을 가져왔다.
제2장 Delphi에서 DLL 파일 작성
DLL 파일을 작성하는 것은 사실 그리 어려운 일이 아니다. 우리가 평소에 Delphi에서 프로그램을 작성하는 것과 기본적으로 비슷하다. 다음은 간단한 예를 들어 설명한다.library DLL;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
ShareMem,
SysUtils,
Classes;
function testStr: TStringList; stdcall;
var
str: string;
strlist: TStringList;
begin
strlist := TStringList.Create;
strlist.Add('hello');
strlist.Add('world');
str := 'hello world';
result := strlist;
end;
function testInt(i: Integer): Integer; stdcall;
begin
Inc(i);
result := i;
end;
{$R *.res}
exports
testStr,
testInt;
begin
end.
위의 Dll 파일에서 두 개의 함수를 봉인했음을 알 수 있습니다.일반적인 Delphi가 작성한 프로그램과 기본적으로 같습니다. DLL 파일의 함수 뒤에 stdcall 인자가 하나 더 있고, 인용할 함수를 exports로 설명합니다.위 코드를 컴파일하면 동적 링크 라이브러리의 Dll 파일을 얻을 수 있습니다.
1, Dll에서 작성한 함수는 stdcall 호출 파라미터를 뒤에 추가해야 합니다. stdcall 파라미터를 추가하는 것을 잊어버리면 컴파일은 통과할 수 있지만, 이 DLL을 호출할 때 심각한 오류가 발생하여 운영체제의 자물쇠가 사라집니다.
2, 쓴 함수와 과정은 exports로 외부 함수로 성명해야 합니다.만약 성명이 없다면, Dll 내부의 함수는 호출할 수 없습니다. 이것은 분명히 우리가 보고 싶은 것이 아닙니다.
3, 긴 문자열 형식의 매개 변수, 변수를 사용할 때,string과 같이 ShareMem을 참조합니다.델피의string 기능은 매우 강하지만, 다른 프로그래밍 언어에 사용할 Dll 파일을 작성할 때 PChar 형식을 사용하는 것이 좋습니다.string 형식의 매개 변수를 계속 사용할 때, 변수, 심지어는 정보를 기록하려면shareMem 단원을 인용해야 합니다. 이 단원은 첫 번째 인용이어야 합니다. 즉uses 문장 뒤의 첫 번째 단원이어야 합니다.다음과 같습니다.uses
ShareMem,
SysUtils,
Classes;
프로젝트 파일 (*.dpr) 의uses에서 첫 번째로shareMem 단원을 참조해야 하는 부분도 있습니다.여기서 주의해야 할 것은*.dpr 파일에서 셀 파일(*.pas) 대신 같은 셀을 추가한 점은 Delphi가 자체적으로 가지고 있는 도움말 파일이 명확하게 설명하지 않아 많은 오해를 낳았습니다.만약 이렇게 하지 않는다면, 당신은 다운되는 대가를 치르게 될 것입니다.string 유형을 사용하지 않는 방법은 PChar 또는 ShortString 유형으로 변환하는 것입니다.
제3장 Dll 파일의 호출
1, 정적 호출
Dll 파일을 호출하는 것이 Dll을 작성하는 것보다 훨씬 쉽습니다. 여기서 먼저 Dll의 정적 호출을 정리합니다.먼저 다음 예제를 살펴보십시오.function testInt(i: Integer): Integer; stdcall; external 'DLL.dll';
procedure TForm1.btn2Click(Sender: TObject);
begin
showMessage(inttostr(testInt(1)));
end;
우리가 하는 유일한 작업은 Dll의 함수 설명을implementation 아래에 놓거나 파일 단원의 var 아래에 놓거나 external 문장으로 Dlll의 위치를 지정하는 것입니다.이렇게 하면 우리는 Dll의 함수를 직접 사용할 수 있다.
1, stdcall 매개 변수를 호출하고 Dll의 함수를 참조할 때도 stdcalll 매개 변수를 사용합니다.
2, Dll 파일의 위치를 external로 선언합니다.파일의 접미사 이름은 반드시 붙여야 합니다.
3, Dll에서 글로벌 변수를 호출할 수 없습니다.DLL에서 글로벌 변수(예: var s:byte)를 선언한 경우이렇게 하면 DLL에서 s라는 전역 변수는 정상적으로 사용할 수 있지만 s는 호출 프로그램에 사용할 수 없고 s는 전역 변수로 호출 프로그램에 전달할 수 없다.그러나 호출 프로그램에서 선언된 변수는 DLL에 매개 변수로 전달될 수 있습니다.
둘째, 동적 호출
Dll 파일을 동적으로 호출하려면 복잡하지만 매우 유연합니다.큰 프로그램을 실행할 때 메모리 공간을 절약할 수 있다.다음 예를 살펴보겠습니다.procedure TForm1.btn1Click(Sender: TObject);
type
Taddc = function: TStringList; stdcall;
var
hh: THandle;
addc: Taddc;
temp: TStringList;
i: Integer;
begin
hh := LoadLibrary('DLL.dll');
try
if hh <> 0 then
@addc := GetProcAddress(hh, PChar('testStr'));
if not (@addc = nil) then
begin
temp := addc;
for i := 0 to temp.Count - 1 do
showMessage(temp[i]);
end
else
begin
RaiseLastWin32Error;
end;
finally
FreeLibrary(hh);
end;
end;
위 코드에서 볼 수 있듯이 이런 동적 호출 기술은 매우 복잡하다.그러나 매개변수를 변경하면 호출된 Dll 파일의 이름을 동적으로 변경할 수 있습니다.
1, type에서 호출할 함수나 과정의 유형을 정의하고, 여기에도 stdcall 인자를 추가합니다.
2, Dll을 놓습니다.위 프로그램에서 우리는 LoadLibray 함수를 사용하여 dll 파일을 불러왔습니다. Dll 파일을 사용했을 때 FreeLibrary 함수를 호출해서 Dll을 방출하는 것을 명심하십시오. 그렇지 않으면 Dll은 Windows를 종료하거나 꺼질 때까지 메모리를 차지할 것입니다.여기서 주의해야 할 것은 dll을 방출할 때 이 dll에 정의된 변수, 과정 등을 가리키는 바늘이 없도록 확보하는 것이다. 그렇지 않으면 정상적으로 방출할 수 없고 채용 방문 충돌이 이상하다.또는 프로그램에 빈 포인터가 생겨서 프로그램이 의외로 중단되었다.
3, 동적 호출된 Dll 함수에서string 형식을 사용했습니다. 두 파일에서ShareMem을 인용했기 때문에string 형식의 데이터는 현재 사용되고 매개 변수로 전달될 수 있습니다.
셋째, 정적과 동적 호출의 대비
1. 정적 방법의 실현은 간단하고 파악하기 쉽다.그리고 일반적으로 속도가 비교적 빠르고 더욱 안전하며 믿을 만하다.그러나 정적 방법은 실행할 때 필요한 Dll을 마운트할 수 없고, 메인 프로그램은 실행할 때 Dll을 불러옵니다. 프로그램이 끝날 때까지 Dll을 놓지 않습니다.
2, 동적 방법은 정적 방법의 부족함을 잘 해결하고 Dll의 함수와 과정에 편리하게 접근할 수 있다.그러나 동적 방법은 완전히 파악하기 어렵다. 사용할 때 서로 다른 함수나 과정 때문에 복잡한 유형과 호출 방법을 많이 정의해야 한다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSON
JSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다.
그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다.
저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
DLL 파일을 작성하는 것은 사실 그리 어려운 일이 아니다. 우리가 평소에 Delphi에서 프로그램을 작성하는 것과 기본적으로 비슷하다. 다음은 간단한 예를 들어 설명한다.
library DLL;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
ShareMem,
SysUtils,
Classes;
function testStr: TStringList; stdcall;
var
str: string;
strlist: TStringList;
begin
strlist := TStringList.Create;
strlist.Add('hello');
strlist.Add('world');
str := 'hello world';
result := strlist;
end;
function testInt(i: Integer): Integer; stdcall;
begin
Inc(i);
result := i;
end;
{$R *.res}
exports
testStr,
testInt;
begin
end.
위의 Dll 파일에서 두 개의 함수를 봉인했음을 알 수 있습니다.일반적인 Delphi가 작성한 프로그램과 기본적으로 같습니다. DLL 파일의 함수 뒤에 stdcall 인자가 하나 더 있고, 인용할 함수를 exports로 설명합니다.위 코드를 컴파일하면 동적 링크 라이브러리의 Dll 파일을 얻을 수 있습니다.
1, Dll에서 작성한 함수는 stdcall 호출 파라미터를 뒤에 추가해야 합니다. stdcall 파라미터를 추가하는 것을 잊어버리면 컴파일은 통과할 수 있지만, 이 DLL을 호출할 때 심각한 오류가 발생하여 운영체제의 자물쇠가 사라집니다.
2, 쓴 함수와 과정은 exports로 외부 함수로 성명해야 합니다.만약 성명이 없다면, Dll 내부의 함수는 호출할 수 없습니다. 이것은 분명히 우리가 보고 싶은 것이 아닙니다.
3, 긴 문자열 형식의 매개 변수, 변수를 사용할 때,string과 같이 ShareMem을 참조합니다.델피의string 기능은 매우 강하지만, 다른 프로그래밍 언어에 사용할 Dll 파일을 작성할 때 PChar 형식을 사용하는 것이 좋습니다.string 형식의 매개 변수를 계속 사용할 때, 변수, 심지어는 정보를 기록하려면shareMem 단원을 인용해야 합니다. 이 단원은 첫 번째 인용이어야 합니다. 즉uses 문장 뒤의 첫 번째 단원이어야 합니다.다음과 같습니다.
uses
ShareMem,
SysUtils,
Classes;
프로젝트 파일 (*.dpr) 의uses에서 첫 번째로shareMem 단원을 참조해야 하는 부분도 있습니다.여기서 주의해야 할 것은*.dpr 파일에서 셀 파일(*.pas) 대신 같은 셀을 추가한 점은 Delphi가 자체적으로 가지고 있는 도움말 파일이 명확하게 설명하지 않아 많은 오해를 낳았습니다.만약 이렇게 하지 않는다면, 당신은 다운되는 대가를 치르게 될 것입니다.string 유형을 사용하지 않는 방법은 PChar 또는 ShortString 유형으로 변환하는 것입니다.
제3장 Dll 파일의 호출
1, 정적 호출
Dll 파일을 호출하는 것이 Dll을 작성하는 것보다 훨씬 쉽습니다. 여기서 먼저 Dll의 정적 호출을 정리합니다.먼저 다음 예제를 살펴보십시오.function testInt(i: Integer): Integer; stdcall; external 'DLL.dll';
procedure TForm1.btn2Click(Sender: TObject);
begin
showMessage(inttostr(testInt(1)));
end;
우리가 하는 유일한 작업은 Dll의 함수 설명을implementation 아래에 놓거나 파일 단원의 var 아래에 놓거나 external 문장으로 Dlll의 위치를 지정하는 것입니다.이렇게 하면 우리는 Dll의 함수를 직접 사용할 수 있다.
1, stdcall 매개 변수를 호출하고 Dll의 함수를 참조할 때도 stdcalll 매개 변수를 사용합니다.
2, Dll 파일의 위치를 external로 선언합니다.파일의 접미사 이름은 반드시 붙여야 합니다.
3, Dll에서 글로벌 변수를 호출할 수 없습니다.DLL에서 글로벌 변수(예: var s:byte)를 선언한 경우이렇게 하면 DLL에서 s라는 전역 변수는 정상적으로 사용할 수 있지만 s는 호출 프로그램에 사용할 수 없고 s는 전역 변수로 호출 프로그램에 전달할 수 없다.그러나 호출 프로그램에서 선언된 변수는 DLL에 매개 변수로 전달될 수 있습니다.
둘째, 동적 호출
Dll 파일을 동적으로 호출하려면 복잡하지만 매우 유연합니다.큰 프로그램을 실행할 때 메모리 공간을 절약할 수 있다.다음 예를 살펴보겠습니다.procedure TForm1.btn1Click(Sender: TObject);
type
Taddc = function: TStringList; stdcall;
var
hh: THandle;
addc: Taddc;
temp: TStringList;
i: Integer;
begin
hh := LoadLibrary('DLL.dll');
try
if hh <> 0 then
@addc := GetProcAddress(hh, PChar('testStr'));
if not (@addc = nil) then
begin
temp := addc;
for i := 0 to temp.Count - 1 do
showMessage(temp[i]);
end
else
begin
RaiseLastWin32Error;
end;
finally
FreeLibrary(hh);
end;
end;
위 코드에서 볼 수 있듯이 이런 동적 호출 기술은 매우 복잡하다.그러나 매개변수를 변경하면 호출된 Dll 파일의 이름을 동적으로 변경할 수 있습니다.
1, type에서 호출할 함수나 과정의 유형을 정의하고, 여기에도 stdcall 인자를 추가합니다.
2, Dll을 놓습니다.위 프로그램에서 우리는 LoadLibray 함수를 사용하여 dll 파일을 불러왔습니다. Dll 파일을 사용했을 때 FreeLibrary 함수를 호출해서 Dll을 방출하는 것을 명심하십시오. 그렇지 않으면 Dll은 Windows를 종료하거나 꺼질 때까지 메모리를 차지할 것입니다.여기서 주의해야 할 것은 dll을 방출할 때 이 dll에 정의된 변수, 과정 등을 가리키는 바늘이 없도록 확보하는 것이다. 그렇지 않으면 정상적으로 방출할 수 없고 채용 방문 충돌이 이상하다.또는 프로그램에 빈 포인터가 생겨서 프로그램이 의외로 중단되었다.
3, 동적 호출된 Dll 함수에서string 형식을 사용했습니다. 두 파일에서ShareMem을 인용했기 때문에string 형식의 데이터는 현재 사용되고 매개 변수로 전달될 수 있습니다.
셋째, 정적과 동적 호출의 대비
1. 정적 방법의 실현은 간단하고 파악하기 쉽다.그리고 일반적으로 속도가 비교적 빠르고 더욱 안전하며 믿을 만하다.그러나 정적 방법은 실행할 때 필요한 Dll을 마운트할 수 없고, 메인 프로그램은 실행할 때 Dll을 불러옵니다. 프로그램이 끝날 때까지 Dll을 놓지 않습니다.
2, 동적 방법은 정적 방법의 부족함을 잘 해결하고 Dll의 함수와 과정에 편리하게 접근할 수 있다.그러나 동적 방법은 완전히 파악하기 어렵다. 사용할 때 서로 다른 함수나 과정 때문에 복잡한 유형과 호출 방법을 많이 정의해야 한다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSON
JSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다.
그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다.
저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
function testInt(i: Integer): Integer; stdcall; external 'DLL.dll';
procedure TForm1.btn2Click(Sender: TObject);
begin
showMessage(inttostr(testInt(1)));
end;
procedure TForm1.btn1Click(Sender: TObject);
type
Taddc = function: TStringList; stdcall;
var
hh: THandle;
addc: Taddc;
temp: TStringList;
i: Integer;
begin
hh := LoadLibrary('DLL.dll');
try
if hh <> 0 then
@addc := GetProcAddress(hh, PChar('testStr'));
if not (@addc = nil) then
begin
temp := addc;
for i := 0 to temp.Count - 1 do
showMessage(temp[i]);
end
else
begin
RaiseLastWin32Error;
end;
finally
FreeLibrary(hh);
end;
end;
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.