软件重用是业界追求的目标,人们一直希望能够像搭积木一样随意"装配"应用程 序,组件对象就充当了积木的角色.所谓组件对象,实际上就是预定义好的,能 完成一定功能的服务或接口.
问题是,这些组件对象如何与应用程序,如何与其 他组件对象共存并相互通信和交互?这就需要制定?个规范,让这些组件对象按 统一的标准方式
工作. COM 是个二进制规范,它与
源代码无关.这样,即使 COM 对象由不同的 编程语言创建,运行在不同的进程空间和不同的操作系统平台,这些对象也能相 互通信 COM 既是规范 也是实现 它以 COM 库(OLE32.dll 和贴 OLEAut32.dll) . , , 的形式提供了访问 COM 对象核心功能的标准接口以及一组 API 函数,这些 API 函数用于创建和管理 COM 对象.COM 本质上仍然是客户服务器模式.客户(通 常是应用程序)请求创建 COM 对象并通过 COM 对象的接口操纵 COM 对象.服 务器根据客户的请求创建并管理 COM 对象.客户和服务器这两种角色并不是绝 对的. 组件对象与一般意义上的对象既相似也有区别.一般意义上的对象是一种把 数据和操纵数据的方法封装在一起的数据类型的实例,而组件对象则使用接口 (Interface)而不是方法来描述自己并提供服务.所谓接口,其精确定义是"基于对 象的一组语义上相关的功能",实际上是一个纯虚类,真正实现接口的是接口对 象)(Interface Object).一个 COM 对象可以只有一个接口,例如 Wndows 95/ 98 外壳扩展;也可以有许多接口,例如 ActiveX 控件一般就有多个接口,客户 可以从很多方面来操纵 ActiveX 控件.接口是客户与服务器通信的唯一途径.如 果一个组件对象有多个接口,则通过一个接口不能直接访问其他接口.但是, COM 允许客户调用 COM 库中的 QueryInterface()去查询组件对象所支持的其他 接口.从这个意义上讲,组件对象有点像接口对象的经纪人. 在调用 QueryInterface()后,如果组件对象正好支持要
查询的接口,则 QueryInterface() 将 返 回 该 接 口 的 指 针 . 如 果 组 件 对 象 不 支 持 该 接 口 , 则 QueryInterface()将返回一个出错信息. 所以,QueryInterface()是很有用的,它可以动态了解组件对象所支持的接 口.接口是团向对象编程思想的一种体现,它隐藏了 COM 对象实现服务的细节. COM 对象可以完全独立于访问它的客户,只要接口本身保持不变即可.如果需 要更新接口,则可以重新定义一个新的接口,对于使用老接口的客户来说,代码 得到了最大程度的保护. Delphi 通过向导可以非常迅速和方便的直接建立实现 COM 对象的代码,但是整 个 COM 实现的过程被完全的封装,甚至没有 VCL 那么结构清晰可见. 一个没有 C++下 COM 开发经验甚至没有接触过 COM 开发的 Delphi 程序员, 也能够很容易的按照教程
设计一个接口, 但是,恐怕深入一想,连生成的代码代表何种意义,哪些能够定制都不清楚.前 几期 "DELPHI 下的 COM 编程技术"一文已经初步介绍了 COM 的一些基本概 念,我则想谈一些个人的理解,希望能给对 Delphi 下 COM 编程有疑惑的朋友 带来帮助. COM (组件对象模型 Component Object Model)是一个很庞大的体系.简单来 说,COM 定义了一组 API 与一个二进制的标准,让来自不同平台,不同开发语
言的独立对象之间进行
通信.COM 对象只有方法和属性,并包含一个或多个接 口.这些接口实现了 COM 对象的功能,通过调用注册的 COM 对象的接口,能 够在不同平台间传递数据. COM 光标准和细节就可以出几本大书.这里避重就轻,仅仅初步的解释 Delphi 如何进行 COM 的封装及实现.对于上述 COM 技术经验不足的 Delphi 程序开发 者来说, Delphi 通过模版生成的代码就像是给你一幅抽象画照着画一样 画出来了却不一 , 定知道画的究竟是什么,也不知该如何下手画自己的东西.本文能够帮助你解决 这类疑惑. 再次讲解一些概念 "DELPHI 下的 COM 编程技术"一文已经介绍了不少 COM 的概念,比如 GUID, CLSID,IID,引用计数,IU