[转]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源模块框架,如下:
| 以下是引用片段: Library project1; {...注释...} uses SysUtils, Classes; begin end |
接下来便可在USES和begin之间加入想在该DLL中实现的过程和函数的定义,并用export和exprots保字把它们引出,以便别的模块引用,在begin和end之间加入初始化代码,初始化代码是用来对DLL变量初始化的。应注意,即便无初始化代码begin与end也不可省略,如下例:
| 以下是引用片段: library minmax; function Min(X, Y: Integer): Integer; export; begin if X < Y then Min := X else Min := Y; end; function Max(X, Y: Integer): Integer; export; begin if X > Y then Max := X else Max := Y; end; end. |
经编译后,并以minmax.DLL存盘后,一个DLL库文件便形成了。
delphi 中动态链接库(dll)的建立和使用 来自: 免费论文网
三 DLL库的访问
访问DLL库有两种方式,一种是静态引用,另一种是动态引用。
用静态引用这种方法装入DLL要做两件事情:为DLL 库创建一个输入单元,以及
用USES把输入单元连接到要使用DLL 函数的程序模块中。为DLL库创建的输入单元与普通的单元的区别仅在于:在它的接口处声明的过程、函数,并不在它的实现部分给出真正的实现代码,而是用external关键字把过程、函数的实现细节委托给外部DLL模块。
external命令的使用语法如下:
procedure /function 过程/函数名;external DLL模块名;
下面给出为上面创建的minmax.DLL库写的输入单元源文件testdll .pas,从中可看出输入单元 与一般 单元的一些差别,代码如下所示:
| 以下是引用片段: unit testdll; interface uses function Min (X, Y: Integer): Integer; function Max (X, Y: Integer): Integer; |
一个应用程序若想调用minmax.DLL中的函数,只须在其uses语句中加入testdll 单元即可。
动态装入DLL,要用到Windows的三个API函数。Loadlibrary、Freelibrary和GetprocAddress 。loadlibrary函数用来装入DLL库,其调用格式如下:
function loadlobrary (DLLfileName:Pchar): THandle:
当不再需要一个DLL库时,应调用FreeLibrary函数将其释放,以空出宝贵的内存资源,其调用格式如下:
procedure FreeLibrary (Libmodule:THandle)
Libmodule 为由LoadLibrary调用得到的DLL库句柄。在用loadlobrary 函数装入某个DLL库和调用FreeLibrary释放该DLL库之间的程序段中, 可以使用该DLL库中的过程和函数,具体使用方法是:用GetprocAddress函数把DLL库中函数的地址传递给程序中某个函数变量,再用该变量实现DLL函数的调用。GetprocAddress函数声名如下,
|
以下是引用片段: |
在调用动态链接库时应注意, 所需动态链接库须与应用程序在同一目录或Windows System 目录下。
动态链接库是 Windows下程序组织的一种重要方式,使用动态链接库可以极大地保护用户在不同开发工具、不同时期所做的工作,提高编程效率。
[转]Delphi 中动态链接库(dll)的建立和使用的更多相关文章
- Delphi 中的DLL 封装和调用对象技术(刘艺,有截图)
Delphi 中的DLL 封装和调用对象技术本文刊登2003 年10 月份出版的Dr.Dobb's 软件研发第3 期刘 艺摘 要DLL 是一种应用最为广泛的动态链接技术但是由于在DLL 中封装和调用对 ...
- delphi 2010 动态链接库DLL断点调试
DELPHI 2010 动态链接库DLL断点调试 马根峰 (广东联合电子服务股份有限公司,广州 510300) 摘要:本文详细介绍了Delphi 2010中的动态链接库DLL断点调试技术 关键词:DE ...
- 在delphi中,DLL加载时做初始化的Demo
library DLLEntry;//dll源码 uses SysUtils, Classes, Dialogs, Windows; {$R *.res} procedure DLLEntryPoin ...
- Delphi中的dll操作
利用delphi dll wizard进行dll的编写. 创建:保存时改dll名称 library test2; uses SysUtils, Classes, forms, dialogs; {$R ...
- Delphi中一些DLL的运用(要传递Application和Screen,似乎还忘了传递提示控件)
dll 调用部分: {****************************************************************} { } { Project: DllDebug ...
- Delphi 使用之dll文件生成与调用
DLL是Dynamic-Link Libraries(动态链接库)的缩写,库里面是一些可执行的模块以及资源(如位图.图标等).可以认为DLL和EXE基本上是一回事,只是DLL不能直接执行,而必须由应用 ...
- delphi中DLL编程详解
10.1 Windows的动态链接库原理 动态链接库(DLLs)是从C语言函数库和Pascal库单元的概念发展而来的.所有的C语言标准库函数都存放在某一函数库中,同时用户也可以用LIB程序创建自己的函 ...
- Delphi中DLL的创建和使用
参考:http://blog.csdn.net/ninetowns2008/article/details/6311663 结合这篇博客:http://www.cnblogs.com/xumenger ...
- ASP.net/C#中如何调用动态链接库DLL
动态链接库(也称为DLL,即为“Dynamic Link Library”的缩写)是Microsoft Windows最重要的组成要素之一,打开Windows系统文件夹,你会发现文件夹中有很多DLL文 ...
随机推荐
- Netty4.0学习笔记系列之三:构建简单的http服务(转)
http://blog.csdn.net/u013252773/article/details/21254257 本文主要介绍如何通过Netty构建一个简单的http服务. 想要实现的目的是: 1.C ...
- [置顶] 技术人血泪史:七种IT失误让你直接走人
IT人士的真实故事:搞出大麻烦,旋即遭解雇 如今想找一份理想的IT工作并不容易,但丢掉一份工作却非常简单. 导致自己被炒鱿鱼的原因很多,无论是没能尽到保护雇主数字资产的义务.或者是滥用手中的权限以达到 ...
- 数据结构(左偏树):HDU 1512 Monkey King
Monkey King Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- 搜索与DP:SLIKAR
Problem: SLIKAR[题目描述]Josip 是个奇怪的画家,他想画一幅由 N*N 个点组成的图, N 是一个 2 的乘方 数(1, 2, 4, 8, 16 等.).每个点要么是黑色的,要么是 ...
- eclipse 导入项目时候java版本不一致问题
最近导入一个java项目,发现我安装的java版本是1.8.0_111,而项目的版本是1.8.0_101,当然不想重新再安装旧的java版本,于是就在网上找了解决方法. 在项目的library中右击, ...
- openStack controller 管理网口TX数据量非常大 网络总是丢包
- 由浅入深吃透MVC框架,驯服烂代码
MVC 已经成为客户端的主流编程框架,相信客户端工程师对它并不陌生,甚至在开发过程中,不通过思考都会自动使用 MVC 框架编程.但在工作过程中,发现许多小伙伴也只是使用 MVC,对于为什么这样使用并不 ...
- SVN强制注释
1.目的 在使用SVN作为版本控制的时候,强制提交的人员写注释,这样能确保每次提交都有注释,方便查看 2.解决办法 2.1给工程加上属性 2.1.1在工程提交之后,通过客户端 ...
- artTemplate的使用总结
原生语法 使用原生语法,需要导入template-native.js文件. 在HTML中定义模板,注意模板的位置,不要放到被渲染区域,防止模板丢失. <script id="main_ ...
- centos 7 安装 mariadb数据库
1.安装MariaDB #安装命令yum install mariadb mariadb-server -y#安装完成MariaDB,首先启动MariaDBsystemctl start mariad ...