Delphi编写DLL(以及静态和动态方式调用)
作者/cadenza7
什么是DLL?
DLL是Dynamic Link Library(动态链接库)的缩写形式。DLL 是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件,动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数,函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL 还有助于共享数据和资源,多个应用程序可同时访问内存中单个DLL 副本的内容,DLL 是一个包含可由多个程序同时使用的代码和数据的库。
Delphi编写DLL
library MyDLL;
{ 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
SysUtils,
Classes;
{$R *.res}
//function MySquare(num:integer):integer;
//加上stdcall表示此DLL文件可以供除Delphi以外程序调用,比如VB、C++等等
//函数MySquare()用于计算一个整数的平方
function MySquare(num:integer):integer;stdcall;
begin
Result:=num*num;
end;
exports
//输出MySquare()函数,必须输出,否则在程序中调用时会提示"无法找到此函数的入口点"
MySquare;
begin
end.
静态加载方式调用DLL
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
//静态调用
function MySquare(i:integer):integer; stdcall; external 'MyDLL.dll';
//静态调用使用别名方式
function MyAsSqr(i:integer):integer; stdcall; external 'MyDLL.dll' name 'MySquare';
var
Form1: TForm1;
//静态调用时也可以定义在这里
//function MySquare(i:integer):integer; stdcall; external 'MyDLL.dll';
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(IntToStr(MySquare(5)));
ShowMessage(IntToStr(MyAsSqr(6)));
end;
end.
动态加载方式调用DLL
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
//Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
//动态调用
TMySquare = function(i:integer):integer; stdcall;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
num: integer;
HndDLL: THandle;
//为便于演示代码,此处使用Func来命名
Func: TMySquare;
//实际开发中我更习惯使用此方式命名
//MySquare: TMySquare;
begin
HndDLL := LoadLibrary('MyDLL.dll');
try
//注意'MySquare'为DLL中的原始名称
@Func := GetProcAddress(HndDLL, 'MySquare');
//@MySquare:= GetProcAddress(HndDLL, 'MySquare');
if Assigned(@Func) then
//if not (@Func=nil) then
begin
num := Func(7);
ShowMessage(IntToStr(num)) ;
//self.Memo1.Lines.Add(IntToStr(num));
end;
finally
FreeLibrary(HndDLL);
end;
end;
end.
静态加载:简单方便。
动态加载:相对复杂一些,需要显示地获取函数调用地址,但比较灵活,对于不常用的代码,使用时LoadLibrary,不用时FreeLibrary,不必长时间占用内存资源。
版权所有,转载请务必标明文章出处或保留以下信息!谢谢!!
作者主页 http://blog.csdn.net/cadenza7