Delphi 中的DLL 封装和调用对象技术(刘艺,有截图)

时间:2022-05-25 00:13:04

Delphi 中的DLL 封装和调用对象技术
本文刊登2003 年10 月份出版的Dr.Dobb‘s 软件研发第3 期
刘 艺
摘 要
DLL 是一种应用最为广泛的动态链接技术但是由于在DLL 中封装和调用对象受到对
象动态绑定机制的限制使得DLL 在封装对象方面有一定的技术难度导致有些Delphi 程
序员误以为DLL 只支持封装函数不支持封装对象本文着重介绍了DLL 中封装和调用对
象的原理和思路并结合实例给出了多种不同的实现方法
关键字动态链接库DLL 对象接口虚方法动态绑定类引用面向对象
1 物理封装与动态链接
物理上的封装意味着将程序封装成若干个独立的物理组成部分各部分之间通过动态链
接共同完成系统的功能而且各个物理组成部分可以单独维护和编译不影响其他部分要
理解物理封装首先要搞清楚静态链接和动态链接
在Delphi 中如果程序的各个模块分别保存在不同的单元文件中并通过uses 指令来
互相调用这就是一个典型的静态链接于是各个静态的子例程编译之后连接器从Delphi
编译过的单元或静态库中取出子例程编译代码并添加到执行文件中最终EXE 文件包
括了程序及其所属单元的所有代码显然静态链接的单元或模块最终以一个独立的物理形
式可执行文件存在除了自己编写的单元文件Delphi 还自动uses 了一些预设的单元
如Windows Messages 等这些都是静态链接
静态链接无法实现物理上的切割和封装而且一旦其中某个单元或模块改动其他所有
单元或模块都得随之重新编译和连接
用于实现物理切割和封装的bpl 包DLL 动态链接库或COM+组件都是一种动态链接
的形式在动态链接情况中连接器只使用子例程external 声明中的信息在执行文件中产生
一些数据表格当Windows 向内存中装载执行文件时它首先装载所有必需的DLL 然后
程序才会启动在装载过程中Windows 用函数在内存中的地址填充程序的内部表格
每当程序调用一个外部函数时它就会使用该内部数据表格直接对DLL 代码它当前
装载在程序的地址空间中进行调用注意该模式不会涉及两个不同的应用程序DLL
已经变成了应用程序的一部分并装载在同一地址空间所有参数的传递都发生在堆栈上
与其它任何函数调用一样这里我们不打算讨论DLL 的编译因为我们首先想重点介绍
Delphi 中的DLL 封装和调用对象技术
2 用DLL 封装对象
DLL Dynamic Link Library 动态链接库就目前来讲已经不再是什么新技术读者可
以在书店过时的Delphi 书籍里随便找到讨论DLL 编程的章节但这些涉及DLL 编程的书
中几乎都是谈论用DLL 来封装函数的实际上大量的程序员也是在使用DLL 来封装函数
或面向过程的一个模块一个函数集合而在这里我只想讨论如何用DLL 来封装对象
这可能是读者未曾有过的DLL 使用经验但这却是这本完全围绕面向对象编程的书中重要
的部分之一或许你能从中发现一些与众不同的实用技巧
参见考虑到目前关于DLL的现成资料很多这里我省略了DLL的基本知识和编写
方法假设读者已经有了一定的DLL编程基础如果你没有这样的基础建议参阅
拙作Delphi6企业级解决方案及应用剖析DLL编程技术一节P271
一般来说使用DLL 封装对象主要有以下好处
?? 节约内存多个程序可以使用同一个DLL 时该DLL 只需加载一次而且可以只
在使用时加载不用时销毁
?? 使程序代码实现复用这就是说用DLL 封装的对象可以重复使用甚至可以让不
同的程序语言调用
?? 使程序模块化组件化这样利于团队开发维护和更新方便
然而DLL 在封装对象方面却有一定的技术难度这方面资料极少甚至有的程序员误
以为DLL 只支持封装函数不支持封装对象
通过研究我们发现DLL 在封装对象上主要的限制在于
?? 调用DLL 的应用程序只能使用DLL 中对象的动态绑定的方法
?? DLL 封装对象的实例只能在DLL 中创建
?? 在DLL 和调用DLL 的应用程序中都需要对封装的对象及其被调用的方法进行声

下面我先通过一个简单的例子来演示如何使用DLL 封装对象并在应用程序中调用该
对象然后再讨论相关的技术细节
3 一个简单的例子
读者一定还记得我们在前面章节中演示了车的继承关系和合成关系这个程序由逻辑单
元的Demo 和界面单元frmDemo 组成我们现在就用DLL 封装Demo 单元的所有对象并
在frmDemo 单元实现调用读者可以通过这个具体的例子来学习如何使用DLL 封装对象
打开项目文件ObjDemo.dpr 如图 1 所示在项目管理器Project Manager 中鼠标
右击ProjectGroup1 然后在弹出菜单中选择Add New Project...菜单项此时弹出如图 2 所
示的New Items 对话框选择DLL Wizard Delphi 的DLL 向导将创建一个DLL 项目我
们将该项目重新命名为DemoSvr 并保存在项目组同一目录下


图 1 鼠标右击ProjectGroup1 在弹出菜单中选择Add New Project...菜单项