Delphi制作DLL


======================================================
注:本文源代码点此下载
======================================================

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;

第二节 dll 中的delphi窗体

一、在dll 中放置窗的的方法

在dll 中,除了放置标准的函数和过程以外,也可以放置已经做好的的delphi窗体,也可以把做好的窗体供其它程序使用,方法是:

1)首先按普通方法制作窗体,不过在interface区域,对接口函数做如下声明

function createform(capt:string):string;stdcall;

2)在implementation下加入接口函数

function createform(capt:string):string;stdcall;

var form1: tform1;

begin

form1:=tform1.create(application);

form1.show;

form1.caption:=capt;

end;

3)制作dll 动态连接库,但要声明:

uses

unit1 in ’unit1.pas’;

exports

{写入接口标示符}

createform name ’myform’;

4)调用窗体的程序按普通方法制作,但是 在implementation下首先声明要调用的dll函数

const

gdi32=’myformdll.dll’;

function createform(capt:string):string;stdcall;external gdi32 name ’myform’;

procedure tform3.button1click(sender: tobject);

var n,m:string;

begin

m:=’我的窗体’;

createform(m);var n,m:string;

end;

二、dll 中的调用窗体时的数据传递

在窗体调用时,可以用普通的函数方法传递数据,下面举个例子。

1)建立窗体

做一个改变颜色窗体,放在dll 中,可以用普通的方法来做,但要作如下声明:

function mycolor(col:longint):longint;stdcall;

function getcolor:longint;stdcall;

其中,mycolor为构造窗体;getcolor为传递颜色数据。

在implementation区声明一个窗体内全局的变量

var color1:longint;

下面写出相应的程序

function mycolor(col:longint):longint;stdcall;

var form1: tform1;

begin

form1:=tform1.create(application);

form1.show;

form1.panel1.color:=col;

form1.edit1.text:=inttostr(form1.panel1.color);

result:=color1;

end;

function getcolor:longint;stdcall;

begin

result:=color1;

end;

procedure tform1.scrollbar1change(sender: tobject);

begin

panel2.color:=rgb(scrollbar1.position,scrollbar2.position,scrollbar3.position);

edit2.text:=inttostr(panel2.color);

color1:=panel2.color;

end;

procedure tform1.button2click(sender: tobject);

begin

free; //析构form1

end;

2)建立动态连接库

运行成功后,再建立动态连接库:

library formdll;

{从文件调入}

uses

unit1 in ’unit1.pas’;

exports

{写入接口标示符}

mycolor name ’my’,

getcolor name ’get’;

begin

end.

3)建立调用的程序

首先声明要调用的dll函数

const

gdi32=’formdll.dll’;

function mycolor(col:longint):longint;stdcall;external gdi32 name ’my’;

function getcolor:longint;stdcall;external gdi32 name ’get’;

然后写出相应的程序

procedure tform1.button1click(sender: tobject);

begin

mycolor(color);

end;

procedure tform1.button2click(sender: tobject);

begin

color:=getcolor;

end;

我们可以看到,在改变颜色的窗体中做了颜色变化后,当前窗体的颜色将发生变化。


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值