Delphi 中动态链接库DLL的建立和使用.docx
- 文档编号:5325995
- 上传时间:2023-05-08
- 格式:DOCX
- 页数:5
- 大小:16.68KB
Delphi 中动态链接库DLL的建立和使用.docx
《Delphi 中动态链接库DLL的建立和使用.docx》由会员分享,可在线阅读,更多相关《Delphi 中动态链接库DLL的建立和使用.docx(5页珍藏版)》请在冰点文库上搜索。
Delphi中动态链接库DLL的建立和使用
Delphi中动态链接库(DLL)的建立和使用
关键词:
动态链接库是一个能够被应用程序和其它的DLL调用的过程和函数的集合体,它里面包含的是公共代码或资源。
由于DLL代码使用了内存共享技术,在某些地方windows也给了DLL一些更高的权限,因而DLL中可以实现一些一般程序所不能实现的功能,如实现windows的HOOK、ISAPI等。
同时,DLL还为不同语言间代码共享提供了一条方便的途径。
因而DLL在编程时应用较为广泛,本文将介绍如何在Delphi中建立和使用DLL。
一.DLL库内存共享机制
从使用效果看,DLL和unit很像,它们都可以被别的工程模块所调用,但二者在内部的实现机制上确存在着差别。
如果一个程序模块中用uses语句引用了某个unit,编译程序在编译该模块时,便会连同unit一起编译,并把编译后的可执行代码链接到本程序模块中,这就是一个程序模块能够调用所引用unit中过程和函数的原因。
当同一个unit被多个工程所引用时,则每个工程中都含有该unit的可执行代码,当含有该unit的多个工程同时执行时,unit的可执行代码会随不同工程而多次被调入内存,造成内存资源的浪费。
DLL则不同,它即使被某个工程调用,编译后仍是独立的,也就是说编译后,一个DLL库形成一个单独的可执行文件,而不与任何其它的可执行文件连接在一起,因而DLL库并不从属于某个特定的工程,当多个工程调用同一个DLL库时只有第一个工程把DLL库调入内存,其余工程并不重复调入同一个DLL库到内存,而是到同一个共享内存区读取。
并且,DLL的执行代码是在程序运行期间动态调入的,而不是如unit在程序运行时就与整个工程一起调入内存。
这样便可消除unit带来的相同代码多处占用内存的弊病。
二Delphi中DLL库的建立
在Delphi环境中,编写一个DLL同编写一个一般的应用程序并没有太大的区别。
事实上作为DLL主体的DLL函数的编写,除了在内存、资源的管理上有所不同外,并不需要其它特别的手段。
一般工程文件的格式为
program 工程标题;
uses 子句;
程序体
而DLLs工程文件的格式为
library工程标题;
uses子句;
exprots子句;
程序体
它们主要的区别有两点
1.一般工程文件的头标用program关键字,而DLL工程文件头标用library关键字。
不同的关键字通知编译器生成不同的可执行文件。
用program关键字生成的是.exe文件,而用library关键字生成的是.dll文件;
2.假如DLL要输出供其它应用程序使用的函数或过程,则必须将这些函数或过程列在exports子句中。
而这些函数或过程本身必须用export编译指令进行编译。
在Delphi主菜单file中选new...项,在弹出的窗口中双击DLL图标,便会自动给出DLL源模块框架,
Libraryproject1;
{...注释...}
uses
SysUtils,Classes;
begin
end.
接下来便可在USES和begin之间加入想在该DLL中实现的过程和函数的定义,并用export和exprots保字把它们引出,以便别的模块引用,在begin和end之间加入初始化代码,初始化代码是用来对DLL变量初始化的。
应注意,即便无初始化代码begin与end也不可省略,如下例:
libraryminmax;
functionMin(X,Y:
Integer):
Integer;export;
begin
ifX YthenMin:
=XelseMin:
=Y;
end;
functionMax(X,Y:
Integer):
Integer;export;
begin
ifX YthenMax:
=XelseMax:
=Y;
end;
exports
Minindex1,
Maxindex2;
begin
end.
经编译后,并以存盘后,一个DLL库文件便形成了。
三DLL库的访问
访问DLL库有两种方式,一种是静态引用,另一种是动态引用。
用静态引用这种方法装入DLL要做两件事情:
为DLL库创建一个输入单元,以及用USES把输入单元连接到要使用DLL函数的程序模块中。
为DLL库创建的输入单元与普通的单元的区别仅在于:
在它的接口处声明的过程、函数,并不在它的实现部分给出真正的实现代码,而是用external关键字把过程、函数的实现细节委托给外部DLL模块。
external命令的使用语法
procedure/function过程/函数名;externalDLL模块名;
下面给出为上面创建的库写的输入单元源文件testdll.pas,从中可看出输入单元与一般单元的一些差别,代码如下所示:
unittestdll;
interface
uses
functionMin(X,Y:
Integer):
Integer;
functionMax(X,Y:
Integer):
Integer;
implementation
functionMin;external‘’;
functionMax;external‘’;
end.
一个应用程序若想调用中的函数,只须在其uses语句中加入testdll单元即可。
动态装入DLL,要用到Windows的三个API函数。
Loadlibrary、Freelibrary和GetprocAddress。
loadlibrary函数用来装入DLL库,其调用格式
functionloadlobrary(DLLfileName:
Pchar):
THandle:
当不再需要一个DLL库时,应调用FreeLibrary函数将其释放,以空出宝贵的内存资源,其调用格式
procedureFreeLibrary(Libmodule:
THandle)
Libmodule为由LoadLibrary调用得到的DLL库句柄。
在用loadlobrary函数装入某个DLL库和调用FreeLibrary释放该DLL库之间的程序段中,可以使用该DLL库中的过程和函数,具体使用方法是:
用GetprocAddress函数把DLL库中函数的地址传递给程序中某个函数变量,再用该变量实现DLL函数的调用。
GetprocAddress函数声名如下,
functionGetprocAddress(Libmodule:
THandle:
procname:
pchar):
TFarProc:
如下例所示:
type
TTimeRec=record
Second:
Integer;
Minute:
Integer;
Hour:
Integer;
end;
TGetTime=procedure(varTime:
TTimeRec);
THandle=Integer;
var
Time:
TTimeRec;
Handle:
THandle;
GetTime:
TGetTime;
begin
Handle:
=LoadLibrary(‘‘);
ifHandle 0then
begin
@GetTime:
=GetProcAddress(Handle,‘GetTime‘);
if@GetTime nilthen
begin
GetTime(Time);
withTimedo
WriteLn(‘Thetimeis‘,Hour,‘:
‘,Minute,‘:
‘,Second);
end;
FreeLibrary(Handle);
end;
end;
在调用动态链接库时应注意,所需动态链接库须与应用程序在同一目录或WindowsSystem目录下。
动态链接库是Windows下程序组织的一种重要方式,使用动态链接库可以极大地保护用户在不同开发工具、不同时期所做的工作,提高编程效率。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Delphi 中动态链接库DLL的建立和使用 动态 链接 DLL 建立 使用
![提示](https://static.bingdoc.com/images/bang_tan.gif)