动态链接库是一个能够被应用程序和其它 的 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; exports Min index 1, Max index 2; begin end. 经编译后,并以 minmax.DLL 存盘后,一个 DLL 库文件便形成了。 三 DLL 库的访问 访问 DLL 库有两种方式,一种是静态引用, 另一种是动态引用。 用静态引用这种方法装入 DLL 要做两件 事情:为 DLL 库创建一个输入单元,以及用 USES 把输入单元连接到要使用 DLL 函数 的程序模块中。为 DLL 库创建的输入单元 与普通的单元的区别仅在于:在它的接口处 声明的过程、函数,并不在它的实现部分给 出真正的实现代码,而是用 external 关键字 把过程、函数的实现细节委托给外部 DLL 模块。