delphi创建DLL动态链接库(A)

delphi创建DLL动态链接库(A)

Windows 的执行文件可以划分为两种形式程序和动态连接库

(DLLs)。一般程序运行是用.EXE文件,但应用程序有时也可以

调用存储在DLL 中的函数。

当我们调用Windows 中的API 函数的时候,实际上就是调用

存储在DLL 中的函数。

在如下几种情况下,调用DLL 是合理的:

1) 不同的程序使用相同的DLL ,这样只需要将DLL 在内存

中装载一次,节省了内存的开销。

2) 当某些内容需要升级的时候,如果使用DLL 只需要改变

DLL 就可以了,而不需要把整个程序都进行变动。

3) 由于DLL 是独立于语言的,所以,当不同语言习惯的人

共同开发一个大型项目的时候,使用DLL 便于程序系统的交流,

当然,Delphi开发的DLL 也可以在诸如Visual BASIC,C++ 等系

统中使用。

下面通过几个例子,说明Delphi开发动态连接库的方法和规

范。

第一节 动态连接库的构建和调用方法

一、动态连接库构建

File—New—Other—DLL Wizard

这就创建了一个动态连接库的基本模块

library Project2;

uses

SysUtils,

Classes;

{$R *.res}

begin

end.

把工程名改为Mydll,并写入必要的函数

library mydll;

uses

SysUtils,Classes,Dialogs,windows;

function Triple(N:Integer):integer;stdcall;

begin

result:=N+3;

end;

function Double(N:Integer):integer;stdcall;

begin

result:=N+2;

end;

function Triple1(N:Integer):integer;stdcall;

begin

showmessage(‘计算N+3’);

result:=N+3;

end;

function Double1(N:Integer):integer;stdcall;

begin

messagebox(0,’计算N+2′,’计算N+2′,mb_ok);

result:=N+2;

end;

exports

Triple name ‘Tr’,

Double name ‘Do’,

Triple1 name ‘TrM’,

Double1 name ‘DoM’;

Triple,Double,Triple1,Double1;

{$R *.RES}

begin

end.

其中函数:Triple:把传入值加三

Double:把传入值加二

Triple1:把传入值加三并显示提示

Double1:把传入值加二并显示提示

从这个例子中可以看出DLL 程序的几个规则:

1) 在DLL 程序中,输出函数必须被声明为stdcall,以使用标

准的Win32 参数传递技术来代替优化的Register。

(说明:在Delphi中Register方式是缺省的调用约定,这个约

定尽量采用寄存器来传递参数,传递次序从左到右,最多可用到3

个CPU 的寄存器,如果参数多于3 个,剩下的就通过栈来传送,使

用寄存器传送可保证参数传递的速度最快。

而stdcall 方式是通过Windows 的标准调用来传递参数,传递

秩序从左到右,这种方式适合调用Windows 的API ,在DLL 中,当

然要使用这种方式)。

2)所有的输出函数都必须列在exports子句下面,这使的子例程

在DLL外部就可以看到。

exports

Triple name ‘Tr’,

Double name ‘Do’,

Triple1 name ‘TrM’,

Double1 name ‘DoM’;

列出了用户使用这个函数的接口名字。虽然别名不是必须的,但

最好给个别名,以便用户程序更容易找到这个函数,同时还要指出,

Delphi 6.0取消了Delphi 5.0中允许使用的index ,如果还用Index

来指明接口名字,Delphi 6.0中将提示错误。

实例中给出了两种提示方法,主要想说明一个问题:

showmessage(”),是VCL 提供的函数,由于多次编译VCL,做出

的程序会比较大。

而messagebox(0,”,”,mb_ok) 是Windows提供的API 函数,做

出的程序会比较小。

这就是说,编写DLL 程序的时候,要尽量避免多次编译VCL 。作

为一个实例,这里把两种方法都列出来了。

保存

编译:Projrct—Build Mydll

这就完成了一个简单的动态连接库的编写。

二、动态连接库的调用

首先在implementation下做调用声明

const

gdi32=’mydll.dll’;

function triple(n:integer):integer;stdcall;external gdi32 name ‘Tr’;

function Double(N:Integer):integer;stdcall;external gdi32 name ‘Do’;

function triple1(n:integer):integer;stdcall;external gdi32 name ‘TrM’;

function Double1(N:Integer):integer;stdcall;external gdi32 name ‘DoM’;

以后程序中就可以作为普通的函数使用了,例如:

procedure TForm1.Button1Click(Sender: TObject);

var N:integer;

begin

N:=updown1.position;

edit1.text:=inttostr(triple(N));

end;



发表评论

您的电子邮箱地址不会被公开。

+ 15 = 19