hina coM 载 第14章COM、COM+和ASP 组件对象模型( Component Object Model,COM)很受编程人员的欢迎,许多使用COM熟 练的开发人员认为COM就像ASP一样能够给编程人员灵感。可以说COM是微软所创造的最优 秀的技术之一。就像ASP一样,COM是任何严谨的 Windows开发者应该了解和掌握的技术。 因此,让我们研究一下COM到底是什么,为什么编程人员这么喜欢它,并且了解COM和ASP 的内在联系,以及如何开发利用它。 令人惊奇的是大多数开发者和最终客户在一些方法、形式上已经不知不觉地运用了COM 作为一个ASP开发者,几乎一直都在使用着COM,所有ASP内置的对象都是COM对象。当用 到这些对象时,就调用了COM对象的方法。IS在很大程度上要用到COM。几乎每个微软产 品都是基于COM或者使用COM。所以不必担心,COM并不是什么新内容而且也不难理解 在 Windows2000中,已经引入了COM+,“+”标志着对COM做了一些重要的改动,即引 入了略有区别的基本编程模型和许多企业级的服务,例如事务管理和有限资源共享 本章将讨论以下内容: COM的内容 COM对开发者的意义。 COM的工作方式。 COM+有哪些改动 用ⅤB编写的一个简单的 ASP COM组件 本章用到COM这个词时,指的是对所有的COM版本都适用的部分,对 Windows 95、 Windows98、 Windows nt和 Windows2000都适用。当用COM+时,指的是 Windows2000中的特殊部分。 14.1COM的内容 cM就是指客户端与CM对象之间交流的一种二进制规范,换句话说,是指它 们如何相互对话。 简单地说,COM是基于对象的,可用合适的编程语言把一些代码变成一个组件,而且允 许在编程语言中运用这个组件或功能,即使使用的语言不同,也不会出现问题,COM考虑到 了这一点。我们不必了解组件程序是如何编写的(用了什么技术、算法等),用的是什么语言, 只须将它作为一个“黑盒子”,知道如何使用,如何通过一个或多个接口(相关功能的集合)来 访问其功能即可。 例如,你知道微软用什么语言编写ASP对象模型或ADO吗?我们只需了解有哪些可用的 COM对象、方法和属性,就能使用它们的功能。这些方法和属性称为对象的接口 如果你认为ASP的 CreateObject函数与 Create COMObject一样, Server create Objecti函数与 Server Create COMObject一样,则说明你知道你在使用COM了
下载 第14章 COM、COM+和ASP 组件对象模型(Component Object Model,C O M )很受编程人员的欢迎,许多使用 C O M熟 练的开发人员认为 C O M就像A S P一样能够给编程人员灵感。可以说 C O M是微软所创造的最优 秀的技术之一。就像 A S P一样, C O M是任何严谨的 Wi n d o w s开发者应该了解和掌握的技术。 因此,让我们研究一下 C O M到底是什么,为什么编程人员这么喜欢它,并且了解 C O M和A S P 的内在联系,以及如何开发利用它。 令人惊奇的是大多数开发者和最终客户在一些方法、形式上已经不知不觉地运用了 C O M。 作为一个A S P开发者,几乎一直都在使用着 C O M,所有A S P内置的对象都是C O M对象。当用 到这些对象时,就调用了 C O M对象的方法。 I I S在很大程度上要用到 C O M。几乎每个微软产 品都是基于C O M或者使用C O M。所以不必担心,C O M并不是什么新内容而且也不难理解。 在Windows 2000中,已经引入了C O M + ,“+”标志着对C O M做了一些重要的改动,即引 入了略有区别的基本编程模型和许多企业级的服务,例如事务管理和有限资源共享。 本章将讨论以下内容: • COM的内容。 • COM对开发者的意义。 • COM的工作方式。 • COM+有哪些改动。 • 用V B编写的一个简单的ASP COM组件。 本章用到C O M这个词时,指的是对所有的 C O M版本都适用的部分,对 Wi n d o w s 9 5、Windows 98、Windows NT和Windows 2000都适用。当用 C O M+时,指的是 Windows 2000中的特殊部分。 14.1 COM的内容 C O M就是指客户端与C O M对象之间交流的一种二进制规范,换句话说,是指它 们如何相互对话。 简单地说,C O M是基于对象的,可用合适的编程语言把一些代码变成一个组件,而且允 许在编程语言中运用这个组件或功能,即使使用的语言不同,也不会出现问题, C O M考虑到 了这一点。我们不必了解组件程序是如何编写的 (用了什么技术、算法等 ),用的是什么语言, 只须将它作为一个“黑盒子”,知道如何使用,如何通过一个或多个接口 (相关功能的集合 )来 访问其功能即可。 例如,你知道微软用什么语言编写 A S P对象模型或A D O吗?我们只需了解有哪些可用的 C O M对象、方法和属性,就能使用它们的功能。这些方法和属性称为对象的接口。 如果你认为 A S P的C r e a t e O b j e c t函数与C r e a e t e C O M O b j e c t一样, S e r v e r. C r e a t e O b j e c t函数与S e r v e r. C r e a t e C O M O b j e c t一样,则说明你知道你在使用 C O M了
434A5p2装程 Chinaopul coM 下载 COM能实现客户与其正在使用的COM对象间的透明定位,客户和组件可运行在不同的进 程中,甚至在不同的机器上。另外COM充分考虑到了机器的远距离连接的需求,使用一个组件 不管距离远近,都用同样的方式。COM提供了完整的基础结构能使所有的组件工作,你只需把 注意力集中在重要的环节上,例如编程和运用组件。COM对客户和组件开发者的要求是 组件开发者应使用一种能创建COM组件的编程语言,例如VB、ⅤC++,所创建的COM 组件符合COM规范 客户有一种编程语言或工具(例如 Microsoft word或ASP),懂得如何实例化和使用COM 组件,而且要遵守COM规范。像 Microsoft word和ASP这样的工具实际上使用其他组件 来完成这种创建,Word用的是VBA,ASP用的是活动脚本( Active Scripting) COM十并未改变COM的基本模型,只是在环境(将在下一章进行更详细的讨论) 方面进行了一些扩展,并且引入了COM+服务 上面已经简单地讲了什么是COM和COM+,其基本原理就是这么简单。 “COM对象”和“COM组件”这两个词经常混用,虽然这从技术上讲并不准确 但一般也不会出错。严格地讲,它们是不同的,前者是后者的一个实例。 14.1.1cOM无处不在 COM很复杂,要想了解COM各方面的细节很费时间,需要大量的阅读和编写代码,一般 来说,要达到熟练并按对COM和COM+的理解编写正确的代码,粗略地算大概需要六个月 然而,如果一开始就在应用程序中充分利用它,并且用ⅤB创建COM组件,正确地练习,则仅 需几个星期。经过一段时间之后,就能掌握基本要点,并能善于使用它。因为理解COM确实 很费时间,所以一开始就要确保经常创建一些可处理的范例。 本书不准备介绍COM的全部内容,也没必要。本章的目的是让读者对COM的关键部分有 个总体的了解,重点介绍一些对ASP组件开发者们很有用的细节。你如果需要更详细地了 解COM,请参阅以下两本好书。 《 Beginning ASP Components》,Wrox出版社出版( ISBN 1-861002-88-2) ·《 VB COM》,Wrox出版社出版(ISBN1-861002-13-0) 下面将详细介绍COM,不必担心刚开始所遇到的任何令人头疼和迷惑的细节,只要认真 学习一切都会解决 141.2cM+的三个方面 COM可以分为三个基本部分 二进制规范。 ·运行期或库。 服务 1.二进制规范 COM规范规定了像ⅤB这样的开发工具在把类模块编译成COM时所需遵守的一些准则 ASP这样的技术用它决定如何创建一个组件(COM对象)的实例并调用它的方法。对开发者们 来说,这个规范也定义了一个跨语言的一致性编程接口。COM规范没限定的是COM自身如何
C O M能实现客户与其正在使用的 C O M对象间的透明定位,客户和组件可运行在不同的进 程中,甚至在不同的机器上。另外C O M充分考虑到了机器的远距离连接的需求,使用一个组件, 不管距离远近,都用同样的方式。C O M提供了完整的基础结构能使所有的组件工作,你只需把 注意力集中在重要的环节上,例如编程和运用组件。C O M对客户和组件开发者的要求是: • 组件开发者应使用一种能创建 C O M组件的编程语言,例如 V B、V C + +,所创建的C O M 组件符合C O M规范。 • 客户有一种编程语言或工具 (例如Microsoft Wo r d或A S P ),懂得如何实例化和使用 C O M 组件,而且要遵守C O M规范。像Microsoft Wo r d和A S P这样的工具实际上使用其他组件 来完成这种创建,Wo r d用的是V B A,A S P用的是活动脚本(Active Scripting)。 C O M+并未改变C O M的基本模型,只是在环境 (将在下一章进行更详细的讨论 ) 方面进行了一些扩展,并且引入了 C O M+服务。 上面已经简单地讲了什么是 C O M和C O M+,其基本原理就是这么简单。 “C O M对象”和“C O M组件”这两个词经常混用,虽然这从技术上讲并不准确, 但一般也不会出错。严格地讲,它们是不同的,前者是后者的一个实例。 14.1.1 COM无处不在 C O M很复杂,要想了解C O M各方面的细节很费时间,需要大量的阅读和编写代码,一般 来说,要达到熟练并按对 C O M和C O M+的理解编写正确的代码,粗略地算大概需要六个月。 然而,如果一开始就在应用程序中充分利用它,并且用 V B创建C O M组件,正确地练习,则仅 需几个星期。经过一段时间之后,就能掌握基本要点,并能善于使用它。因为理解 C O M确实 很费时间,所以一开始就要确保经常创建一些可处理的范例。 本书不准备介绍C O M的全部内容,也没必要。本章的目的是让读者对 C O M的关键部分有 一个总体的了解,重点介绍一些对 A S P组件开发者们很有用的细节。你如果需要更详细地了 解C O M,请参阅以下两本好书。 • 《Beginning ASP Components》,Wrox 出版社出版(ISBN 1-861002-88-2) • 《VB COM》,Wrox 出版社出版(ISBN 1-861002-13-0)。 下面将详细介绍 C O M,不必担心刚开始所遇到的任何令人头疼和迷惑的细节,只要认真 学习一切都会解决。 14.1.2 COM+的三个方面 C O M可以分为三个基本部分 • 二进制规范。 • 运行期或库。 • 服务。 1. 二进制规范 C O M规范规定了像 V B这样的开发工具在把类模块编译成 C O M时所需遵守的一些准则。 A S P这样的技术用它决定如何创建一个组件 ( C O M对象)的实例并调用它的方法。对开发者们 来说,这个规范也定义了一个跨语言的一致性编程接口。 C O M规范没限定的是C O M自身如何 434计计ASP 3 高级编程 下载
a→o 第14章(COM、COM+和sp435 载 实现 在本书印刷的时候,COM规范在已放在下面的网站上http://www.micrOsoft om/com/resources/comdocs asp 所有COM规范都是用一种语言中立方式制定的,这使编写客户端程序所使用的语言与编 写COM对象所使用的语言可以不同,只要支持COM规范即可。请记住,COM是一种二进制 因为COM定义了这个通用的基于对象的通信中介,它真正简化了传统的一些繁重的过程 过去编写客户端/服务器应用程序,必须为不同的客户类型编写多种AP(例如,VC++和VB各 种)。试想在ⅤB这样的程序语言中使用C/C++的 declare语句的功能,ⅤB程序员经常被不必 要的内容搞糊涂,而且不得不弄懂C/C++的结构。然而也许有人会说 declare语句和其他的语 言组接机制并不太差,但是COM更简单,采用的是一种更自然和更一致的方式 2.运行期或/库 COM运行期就是COM规范的一种实现,并且随各种版本的 Windows提供。尽管运行期的 核心API是在ole32d中,但其本身存在于许多DLL中。在开发ASP时,我们时刻都使用着 COM运行期和像ole32d这样的DLL提供的所有功能。尽管有时我们并不知道,但为了完成 任务确实调用了COM运行期 COM运行期有时被称为COM库。但作者偏爱前者,因为这暗示环境是“执行期 间”;有些人喜欢用后者,因为它也是一个函数库。COM运行期是一个主要的内容, 希望大家能熟练地运用它。 (1)ASP页面中的COM客户 在ASP页面中,通过ASP解释器间接地使用 COM运行期,而ASP解释器在技术上使用活动 脚本,这个技术把 VBScript、 Javascript和其他 ASP解释器 活动脚本 脚本语言转换成COM调用,其过程如图14-1所 COM运行期 例如,当在ASP页面中使用 CreateObject或 Server. CreateObjct函数时,可用下面的代码: 图14-1ASP页在与COM运行期的关系 let ob]Conn Createobject( 'ADODB Connection) ASP页面的代码由ASP解释器的活动脚本引擎转换为对COM运行期的调用。COM运行期 际负责创建 ADO Connection对象。 (2)ⅤB中的COM客户 在VB中,使用NEW语句时,就会调用COM运行期。当使用 References对话框向一个项目 增加ADO支持时,所做的一切就是告诉VB你所要使用的一些COM组件。所选择的引用决定 了这些组件,并且允许像使用任何其他ⅤB固有类型一样使用它们: Dim objconn As ADODB Connection Set objconn New ADODB Connection
实现。 在本书印刷的时候, COM 规范在已放在下面的网站上: h t t p : / / W W W. m i c r o s o f t . c o m / c o m / r e s o u r c e s / c o m d o c s . a s p 所有C O M规范都是用一种语言中立方式制定的,这使编写客户端程序所使用的语言与编 写C O M对象所使用的语言可以不同,只要支持 C O M规范即可。请记住, C O M是一种二进制 规范。 因为C O M定义了这个通用的基于对象的通信中介,它真正简化了传统的一些繁重的过程。 过去编写客户端 /服务器应用程序,必须为不同的客户类型编写多种 A P I (例如,V C + +和V B各 一种)。试想在V B这样的程序语言中使用 C / C + +的d e c l a r e语句的功能,V B程序员经常被不必 要的内容搞糊涂,而且不得不弄懂 C / C + +的结构。然而也许有人会说 d e c l a r e语句和其他的语 言组接机制并不太差,但是 C O M更简单,采用的是一种更自然和更一致的方式。 2. 运行期或/库 C O M运行期就是C O M规范的一种实现,并且随各种版本的 Wi n d o w s提供。尽管运行期的 核心A P I是在o l e 3 2 . d l l中,但其本身存在于许多 D L L中。在开发 A S P时,我们时刻都使用着 C O M运行期和像o l e 3 2 . d l l这样的D L L提供的所有功能。尽管有时我们并不知道,但为了完成 任务确实调用了C O M运行期。 C O M运行期有时被称为 C O M库。但作者偏爱前者,因为这暗示环境是“执行期 间”;有些人喜欢用后者,因为它也是一个函数库。 C O M运行期是一个主要的内容, 希望大家能熟练地运用它。 (1) ASP页面中的C O M客户 在A S P页面中,通过A S P解释器间接地使用 C O M运行期,而 A S P解释器在技术上使用活动 脚本,这个技术把 V B S c r i p t、J a v a S c r i p t和其他 脚本语言转换成 C O M调用,其过程如图 1 4 - 1所 示。 例如,当在A S P页面中使用C r e a t e O b j e c t或 S e r v e r. C r e a t e O b j c t函数时,可用下面的代码: A S P页面的代码由A S P解释器的活动脚本引擎转换为对 C O M运行期的调用。 C O M运行期 实际负责创建ADO Connection对象。 (2) VB中的C O M客户 在V B中,使用N E W语句时,就会调用C O M运行期。当使用R e f e r e n c e s对话框向一个项目 增加A D O支持时,所做的一切就是告诉 V B你所要使用的一些 C O M组件。所选择的引用决定 了这些组件,并且允许像使用任何其他 V B固有类型一样使用它们: 第1 4章 C O M、C O M +和A S P计计435 下载 图14-1 ASP页在与C O M运行期的关系 ASP解释器 活动脚本 COM运行期
436 ASP3高级编程 Chinapub.com 下载 作为一位开发者,你发现运行期是COM中一个非常有用的部分。COM规范是COM的准 则,从细节上规定了所有的方面(我们应该了解它),但我们每天所用的是运行期。 在ⅤB中,如果创建的组件不在相同的DLL中,new语句只能转入COM运行期,如果是在 相同的DLL中,则VB不需要使用COM运行期,这时VB可以直创建组件 (3)服务 服务是一些编译过的代码(目前只有微软能 编写)。它们能提供一些可以增强组件能力的 且容易使用的重要功能。如果你用过MTS,应 该用过声明属性和声明安全,通过这两种方法 管理员在运行期可以影响组件的行为和使用 cM+中的属性是二项描述组件的运行期 来设置它们。通过用这种方法设置组件的一种 或多种属性,就能控制它的运行期而不需要额 外的编程和重新编译,这是重用代码的最优形 式。可以充分利用微软编写的基本代码而不是 由自己来开发。例如,一个COM+应用程序的 Transactions选项卡,如图14-2所示 在此选项卡中选择 Required选项,就告诉 图14-2 Transactions选项卡 了COM+我们所用的组件要用COM+提供的事务服务,即告诉COM+每个新的组件实例都 应加入到一个事务中。 在第19章将要讲到,事务处理能使一组组件做为一个整体单位共同工作。 (4)没有COM,ASP将不再是ASP 没有cOM,ASP就不会这么容易扩充,使用也不会如此简单,也许它将不存 除非ASP是建立在一些相同的规范/实现,否则就必须以不同的方式调用不同的组件,而 且要根据组件是用什么语言编写的或者是哪个公司提供的。设想一下,为了能引用组件的 些方法,必须弄懂所有方式,这是C++开发者多年以来一直面对的一个问题,到今也没解决 但是COM解决了,因为最近许多公司都逐渐适应了COM。没有COM,就要花很多时间弄懂组 件编写者的意图及不同的API。应该感谢COM提供了一个容易使用和基于对象编程的范型 微软估计有300万开发者利用COM开发COM应用程序,每天有2亿人使用COM应 用程序,这使COM成为世界范围内最成功的对象模型。 141.3cOM开发工具 就编写组件的语言而言,微软所提供的主要是C++和VB,本书中两者都要讲到 ⅤC++在性能和灵活性的统一上有些缺陷,它使开发者需要深入理解COM的内部工作情 况。但是,一旦理解了,再使用微软活动模板库( Active tieplate library,ATL),编写组件就 像用VB一样又快又简单。但首先,必须了解相应的内容
作为一位开发者,你发现运行期是 C O M中一个非常有用的部分。 C O M规范是C O M的准 则,从细节上规定了所有的方面 (我们应该了解它),但我们每天所用的是运行期。 在V B中,如果创建的组件不在相同的 D L L中,n e w语句只能转入C O M运行期,如果是在 相同的D L L中,则V B不需要使用C O M运行期,这时V B可以直创建组件。 (3) 服务 服务是一些编译过的代码(目前只有微软能 编写)。它们能提供一些可以增强组件能力的 且容易使用的重要功能。如果你用过 M T S,应 该用过声明属性和声明安全,通过这两种方法 管理员在运行期可以影响组件的行为和使用。 C O M+中的属性是一项描述组件的运行期 特性的信息 (元数据 ),可以用组件服务浏览器 来设置它们。通过用这种方法设置组件的一种 或多种属性,就能控制它的运行期而不需要额 外的编程和重新编译,这是重用代码的最优形 式。可以充分利用微软编写的基本代码而不是 由自己来开发。例如,一个 C O M+应用程序的 Tr a n s a c t i o n s选项卡,如图1 4 - 2所示。 在此选项卡中选择 R e q u i r e d选项,就告诉 了C O M+我们所用的组件要用 C O M+提供的事务服务,即告诉 C O M+每个新的组件实例都 应加入到一个事务中。 在第1 9章将要讲到,事务处理能使一组组件做为一个整体单位共同工作。 (4) 没有C O M,A S P将不再是ASP 没有C O M,A S P就不会这么容易扩充,使用也不会如此简单,也许它将不存 在。 除非A S P是建立在一些相同的规范/实现,否则就必须以不同的方式调用不同的组件,而 且要根据组件是用什么语言编写的或者是哪个公司提供的。设想一下,为了能引用组件的一 些方法,必须弄懂所有方式,这是 C + +开发者多年以来一直面对的一个问题,到今也没解决。 但是C O M解决了,因为最近许多公司都逐渐适应了 C O M。没有C O M,就要花很多时间弄懂组 件编写者的意图及不同的A P I。应该感谢C O M提供了一个容易使用和基于对象编程的范型。 微软估计有3 0 0万开发者利用C O M开发C O M应用程序,每天有2亿人使用C O M应 用程序,这使C O M成为世界范围内最成功的对象模型。 14.1.3 COM开发工具 就编写组件的语言而言,微软所提供的主要是 V C + +和V B,本书中两者都要讲到。 V C + +在性能和灵活性的统一上有些缺陷,它使开发者需要深入理解 C O M的内部工作情 况。但是,一旦理解了,再使用微软活动模板库 (Active timeplate library,AT L ),编写组件就 像用V B一样又快又简单。但首先,必须了解相应的内容。 436计计ASP 3 高级编程 下载 图14-2 Tr a n s a c t i o n s选项卡
Sinapub.com 载 第14章COM、COM+和sp437 VB是一个很好的折衷方案 如果想不需经过长时间的COM学习就能快速地编写组件,并且对组件的性能要求不高, 那么使用VB是一种很好的折衷方案。VB隐含了大部分的COM运行期库,这意味着不需再花 时间学习COM,就可以编写COM组件;如果用其他的语言,例如C++,则必须熟悉COM之 后才能创建COM组件。 在VB中,对COM有一点基本的理解就能帮助我们优化组件(通过理解为什么要那样做), 这就是我们要介绍更多关于COM的内容的原因。尽管ⅤB隐含了COM的大部分,理解ⅤB如何 将其语言结构映射到COM,并且了解VB中COM的限制是很重要的 VB是ASP的自然发展道路,尤其是对那些习惯于使用Ⅴ SCript工作的人。本书将用很大 的篇幅讲述如何用ⅤB开发组件,同样也会讲述如何使用C++开发组件,这与Java有一些相似 处。我们还要讲述如何用 JavaScript开发组件。 本书用VB60作为开发工具,尽管ⅤB60与VB50稍微有一点不同,但对于本书 讲述的一些主要内容,用早期的版本一样可以做。 142接口 COM领域的许多人认为COM最重要的和最强大的方面是基于接口的编程。 如果编写代码去完成某项功能的话,其接口就是一系列定义某些东西如何使用 的方法。 功能与实现的抽象观念已存在多年。只要有一些面向对象的知识的人都会很快对抽象数 据类型( Abstrct Data Type,ADT)做一个正确的比较。 基于接口编程就好像控制电视机,遥控器使我们能够通过一个接口来遥控电视,并不 要知道遥控器的内部工作方式,但应知道如何通过遥控器上的各种按钮来控制选台、调节音 量和开关电视 遥控器按钮提供的功能可以由一个接口定义,称为 IRemotcontrol。通过这个接口,各种 控制就能实现,遥控器接口具有表14-1所示的方法。 表14-1遥控器接口具有的方法及说明 说明 如果电视机已经打开,则关闭:反之亦然 Change channe 转换到指定的频道 增加音量 Decrease volume 降低音量 Getchannel 返回目前选定的频道 如果有不同厂家生产的三台电视机,由于使用了接口定义,各个遥控器都能使用上述 方法实现相同的功能,每个遥控器也许内部工作情况不同,但知道如何使用接口(这里的接口 就是遥控器上的按钮)就足够了,只要知道面前是哪台电视机,就能通过他的遥控器调换频道, 看自己喜欢的节目 从内部过程看,遥控器上接口的实现是通过另外一个COM接口与电视机交流,这个接 就是 TElevision,这个接口有与 I Remote control相似的方法。如果每台电视机都实现相同
V B是一个很好的折衷方案 如果想不需经过长时间的 C O M学习就能快速地编写组件,并且对组件的性能要求不高, 那么使用V B是一种很好的折衷方案。 V B隐含了大部分的 C O M运行期库,这意味着不需再花 时间学习C O M,就可以编写C O M组件;如果用其他的语言,例如 V C + +,则必须熟悉C O M之 后才能创建C O M组件。 在V B中,对C O M有一点基本的理解就能帮助我们优化组件 (通过理解为什么要那样做 ), 这就是我们要介绍更多关于 C O M的内容的原因。尽管 V B隐含了C O M的大部分,理解V B如何 将其语言结构映射到C O M,并且了解V B中C O M的限制是很重要的。 V B是A S P的自然发展道路,尤其是对那些习惯于使用 V B S c r i p t工作的人。本书将用很大 的篇幅讲述如何用 V B开发组件,同样也会讲述如何使用 C + +开发组件,这与 J a v a有一些相似 之处。我们还要讲述如何用 J a v a S c r i p t开发组件。 本书用VB 6.0作为开发工具,尽管VB 6.0与VB 5.0稍微有一点不同,但对于本书 讲述的一些主要内容,用早期的版本一样可以做。 14.2 接口 C O M领域的许多人认为C O M最重要的和最强大的方面是基于接口的编程。 如果编写代码去完成某项功能的话,其接口就是一系列定义某些东西如何使用 的方法。 功能与实现的抽象观念已存在多年。只要有一些面向对象的知识的人都会很快对抽象数 据类型(Abstrct Data Ty p e,A D T )做一个正确的比较。 基于接口编程就好像控制电视机,遥控器使我们能够通过一个接口来遥控电视,并不需 要知道遥控器的内部工作方式,但应知道如何通过遥控器上的各种按钮来控制选台、调节音 量和开关电视。 遥控器按钮提供的功能可以由一个接口定义,称为 I R e m o t C o n t r o l。通过这个接口,各种 控制就能实现,遥控器接口具有表 1 4 - 1所示的方法。 表14-1 遥控器接口具有的方法及说明 方 法 说 明 Tu r n O n O ff 如果电视机已经打开,则关闭;反之亦然 C h a n g e C h a n n e l 转换到指定的频道 I n c r e a s e Vo l u m e 增加音量 D e c r e a s e Vo l u m e 降低音量 G e t C h a n n e l 返回目前选定的频道 如果有不同厂家生产的三台电视机,由于使用了接口定义,各个遥控器都能使用上述的 方法实现相同的功能,每个遥控器也许内部工作情况不同,但知道如何使用接口 (这里的接口 就是遥控器上的按钮)就足够了,只要知道面前是哪台电视机,就能通过他的遥控器调换频道, 看自己喜欢的节目。 从内部过程看,遥控器上接口的实现是通过另外一个 C O M接口与电视机交流,这个接口 就是I Te l e v i s i o n,这个接口有与 I R e m o t e C o n t r o l相似的方法。如果每台电视机都实现相同 第1 4章 C O M、C O M +和A S P计计437 下载
438 ASP3高级编程 China pul coM 下载 TElevision接口,那么一个遥控器就能控制所有的电视机!不管电视机是哪个厂家生产的,只 要提供的控制接口相同,遥控器就能控制它。 1421组件 上面例子中的遥控器就是一个COM组件,在VB中编译一个包含在一个 ActiveX项目中的 类模块时,就创建了一个组件,如果这个项目含有多个类模块,那么就创建了多个组件 组件就是通过实现一个或多个接口来提供功能的某种东西 简单地说,组件就是一个具有唯一名称的功能体,并以某种形式的DLL或EXE封装或分 布。在VB中编译一个含有四个类模块的 Activex对象时,所创建的就是含有四个COM组件的 COM服务器,每个组件对应一个类模块,生成了四个COM接口,每个接口对应一个组件,这 些接口(类模块)通常提供了能够访问的方法和属性。类模块与COM组件的关系如图14-3所示 VB Activex项目 COM服务器 类模块 COM组件 COM组件 类模块 类模块 COM组件 COM组件 图14-3类模块与COM组件的关系 棒形图( Lollypop Diagram) COM中运用了一种简单的图解方法来表现组件支 持的接口,即棒形图。这些棒形图中用一个方框表示 REmote Control 组件,方框中的名称就是组件名称,方框左侧伸出的 o大遥控器 部分表示组件的接口,方框上方伸出的单线表示一个 称为 IUnknown的接口,这是每个组件必须实现的,下 I control 面很快就要讲述这个重要的接口。 小遥控器 遥控器的棒形图如图14-4所示 这个图显示了两个组件(电视机),通过 REmote Control接口提供简单的频道变换能力,换句话说就是 14-4遥控器棒形图 遥控。这个图并不复杂,但清楚地表示了可以用它来控制电视机 IUnknoun接口是唯一从方框上面出去的接口,所以在图上未标注它。 1422缺省接口 创建COM组件时,这个组件可以包含很多接口,COM允许把其中一个接口设置为客户使 用的缺省接口,不能自己选择指定接口的客户将使用缺省接口,其理由下面讲述。 在VB中创建一个类模块,并编译成一个组件时,并不能控制哪个接口成为缺省接口, 个缺省接口通常不仅包括所定义的类模块,还包括公共的方法和属性。可以通过使用
I Te l e v i s i o n接口,那么一个遥控器就能控制所有的电视机!不管电视机是哪个厂家生产的,只 要提供的控制接口相同,遥控器就能控制它。 14.2.1 组件 上面例子中的遥控器就是一个 C O M组件,在V B中编译一个包含在一个 A c t i v e X项目中的 类模块时,就创建了一个组件,如果这个项目含有多个类模块,那么就创建了多个组件。 组件就是通过实现一个或多个接口来提供功能的某种东西。 简单地说,组件就是一个具有唯一名称的功能体,并以某种形式的 D L L或E X E封装或分 布。在V B中编译一个含有四个类模块的 A c t i v e x对象时,所创建的就是含有四个 C O M组件的 C O M服务器,每个组件对应一个类模块,生成了四个 C O M接口,每个接口对应一个组件,这 些接口(类模块)通常提供了能够访问的方法和属性。类模块与 C O M组件的关系如图1 4 - 3所示。 图14-3 类模块与C O M组件的关系 棒形图(Lollypop Diagram) C O M中运用了一种简单的图解方法来表现组件支 持的接口,即棒形图。这些棒形图中用一个方框表示 组件,方框中的名称就是组件名称,方框左侧伸出的 部分表示组件的接口,方框上方伸出的单线表示一个 称为I U n k n o w n的接口,这是每个组件必须实现的,下 面很快就要讲述这个重要的接口。 遥控器的棒形图如图1 4 - 4所示。 这个图显示了两个组件 (电视机 ),通过 I R e m o t e C o n t r o l接口提供简单的频道变换能力,换句话说就是 遥控。这个图并不复杂,但清楚地表示了可以用它来控制电视机。 I U n k n o u n接口是唯一从方框上面出去的接口,所以在图上未标注它。 14.2.2 缺省接口 创建C O M组件时,这个组件可以包含很多接口, C O M允许把其中一个接口设置为客户使 用的缺省接口,不能自己选择指定接口的客户将使用缺省接口,其理由下面讲述。 在V B中创建一个类模块,并编译成一个组件时,并不能控制哪个接口成为缺省接口,一 个缺省接口通常不仅包括所定义的类模块,还包括公共的方法和属性。可以通过使用 438计计ASP 3 高级编程 下载 VB ActiveX项目 类模块 类模块 编译 COM组件 COM组件 COM组件 COM组件 COM服务器 类模块 类模块 图14-4 遥控器棒形图 IRemoteControl 大遥控器 小遥控器 IRemoteControl
chinapub coM BIu& COM. COM. RASP 439 下载 Implements关键字使得一个类模块支持附加的接口,但缺省时ASP不能调用这些接口的方法 在 ActiveX项目中创建一个公共类模块时,B所创建的接口的名称就是类模块的 名称前加一个短下划线,例如,MyTv类模块的缺省接口就是_MyTV 1423GUID—实体的确定名称 编译一个类模块并创建一个COM组件时,VB就为这件组件赋予了一个全局唯一的标识符, 称为GUID,GUID是一个根据系统时钟和网卡的MAC地址生成的一个128位的数字,保证是 如果没有网卡,GUID仍然是唯一的,但只能保证在本地计算机中是唯一的 GUID是一些标识符的专用术语,这些标识符跨时间和空间唯一准确地表示一个实体,由 于GUID采用128位数,按每秒增加一千万个GUID的速度,可以使用到公元5770年 当GIUD用来标识一个类模块时,被称为类标识符( CLSID)。在COM中,可以使用GUID 来标识很多东西,所以,在不同的环境中GUID有不同的名称,这些环境包括接口标识符(ID) 和应用程序标识符( APPID) GUID的用途 为什么需要用一个128位数字来标识一个组件?难道是我们给类模块取的名称不够用吗? 答案当然否定的。全球所有的分析家和开发人员每时每刻都在给他们的类模块命名(逻辑名称), 所以两个人同时使用同一种逻辑名称的情况会经常出现,尤其是当人们为同一个范围的问题 设计应用程序时。解决这个问题的办法就是在名字中增加一部分标识符,这并不困难 128位数字是毫无含义的,也不好使用。人们在注册和其他必须处理GUID的地方用一个 字符串来代替GUID。以下的 CLSID用来标识(物理名称)用于微软 ADO Connection组件的一个 组件: 00000293-0000-0010-8000-00AA006D2EA4 这不是一个程序化的标识符( ProgID),后面将讨论PogD 1424接口的详细内容 正如前面提到的,COM是一种二进制规范,这个二进制规范包括描述一个接口在存储器 中的形式以及如何在运行期中访问 虚拟方法表 定义一个接口时,接口方法的次序、每一种方法的参数和各种其他的属性,例如接口的 GUID等,都要通过接口特征来定义。当编译一个包含COM组件的DLL或EXE文件时,接口 特征(二进制形式)就被转换进创建的文件,这个信息用来建立虚拟方法表( vtable),它决定 个客户在运行期如何调用接口的各种方法。为了便于理解,可以把一个 vtable看作一个含有各 种函数的N维数组,这里的N表示一个接口所含方法的个数,如图14-5所示 这个数组实际上并不含有代码,但含有能定位代码地址的指针。因此,通过使用 vtable 可知下标0的项目指向 TurnOn’方法,下标1的项目指向 Change Channel方法,等等。 当编译使用一个接口的客户代码时,这些数组下标(例如0,1,…)就放置在所创建的DLL 戊EXE中,这就是早期绑定。客户知道如何通过按给定的偏移量访问某个函数,从而调用接
I m p l e m e n t s关键字使得一个类模块支持附加的接口,但缺省时 A S P不能调用这些接口的方法。 在A c t i v e X项目中创建一个公共类模块时, V B所创建的接口的名称就是类模块的 名称前加一个短下划线,例如, M y T V类模块的缺省接口就是_ M y T V。 14.2.3 GUID—实体的确定名称 编译一个类模块并创建一个 C O M组件时,V B就为这件组件赋予了一个全局唯一的标识符, 称为G U I D,G U I D是一个根据系统时钟和网卡的 M A C地址生成的一个 1 2 8位的数字,保证是 唯一的。 如果没有网卡,G U I D仍然是唯一的,但只能保证在本地计算机中是唯一的。 G U I D是一些标识符的专用术语,这些标识符跨时间和空间唯一准确地表示一个实体,由 于G U I D采用1 2 8位数,按每秒增加一千万个 G U I D的速度,可以使用到公元5 7 7 0年。 当G I U D用来标识一个类模块时,被称为类标识符 ( C L S I D )。在C O M中,可以使用G U I D 来标识很多东西,所以,在不同的环境中 G U I D有不同的名称,这些环境包括接口标识符 ( I I D ) 和应用程序标识符( A P P I D )。 G U I D的用途 为什么需要用一个1 2 8位数字来标识一个组件?难道是我们给类模块取的名称不够用吗? 答案当然否定的。全球所有的分析家和开发人员每时每刻都在给他们的类模块命名 (逻辑名称), 所以两个人同时使用同一种逻辑名称的情况会经常出现,尤其是当人们为同一个范围的问题 设计应用程序时。解决这个问题的办法就是在名字中增加一部分标识符,这并不困难。 1 2 8位数字是毫无含义的,也不好使用。人们在注册和其他必须处理 G U I D的地方用一个 字符串来代替G U I D。以下的C L S I D用来标识(物理名称)用于微软ADO Co n n e c t i o n组件的一个 组件: 这不是一个程序化的标识符 ( P r o g I D ),后面将讨论P r o g I D。 14.2.4 接口的详细内容 正如前面提到的, C O M是一种二进制规范,这个二进制规范包括描述一个接口在存储器 中的形式以及如何在运行期中访问。 1. 虚拟方法表 定义一个接口时,接口方法的次序、每一种方法的参数和各种其他的属性,例如接口的 G U I D等,都要通过接口特征来定义。当编译一个包含 C O M组件的D L L或E X E文件时,接口 特征(二进制形式)就被转换进创建的文件,这个信息用来建立虚拟方法表 ( v t a b l e ),它决定一 个客户在运行期如何调用接口的各种方法。为了便于理解,可以把一个 v t a b l e看作一个含有各 种函数的N维数组,这里的N表示一个接口所含方法的个数,如图 1 4 - 5所示。 这个数组实际上并不含有代码,但含有能定位代码地址的指针。因此,通过使用 v t a b l e, 可知下标0的项目指向Tu r n O n O ff方法,下标1的项目指向C h a n g e C h a n n e l方法,等等。 当编译使用一个接口的客户代码时,这些数组下标 (例如0,1,. . . )就放置在所创建的D L L 或E X E中,这就是早期绑定。客户知道如何通过按给定的偏移量访问某个函数,从而调用接 第1 4章 C O M、C O M +和A S P计计439 下载
440Ap;高箱程 Chinapub.coM 下载 口中的一个方法。客户不必在运行期查询任何附加信息,只要有接口指针就能进行调用。接 口指针是一种指向可以调用的函数的数组的指针 Remote control Public Sub TurnOnoffo Change channe ot On/off Increase volume Public Sub Change Channel(Number) Decreasevolume End Sub Getchannel 图14-5虚拟方法表 属性就是函数 提供读写对象的数据(或状态)的能力的接口方法叫做属性。下面讲述的方法与C++中的方 法类似,但与ⅤB中给出的例子不同。从语义的角度看它们是相同的,VB也是一种很好的工 具:但在实现时却不是,VB引入的封裝层可能导致人们的误解。 只读属性等同于单个接口方法,该方法允许读取一个值。 ·只写属性等同于单个接口方法,该方法允许更新一个值。 读/写属性等同于两个接口方法,两个方法分别允许读取和更新一个值。 因此,如果有四个读/写属性,VB就会创建8个方法来读取和更新这四个值。 2.接口的要素 一般来说,接口通常至少有一个方法,最多1024个(COM和跨场所调度的限制导致的限 制),一个接口有多少方法是一个设计问题,这个问题是由程序员决定的,可以有一个或者多 个,但不是必须有,一个接口可以没有方法。通常一个设计得很好的接口的方法不超过10到 个 没有方法的接口是不常见的,但也是有用的。它常用于提供组件和顾客间的一种秘密交 流或信号,就像你约好了一没见过面的人,约定他穿着一件特别的衣服,因而当你在人多的 场合遇见他时,能很快识别他。客户通过接口能检查确保组件是存在的 这里的要素化指的是逻辑上把相关的方法一起放到一个接口,因此,如果我说 小心接口要素化,意思是你应当特别注意那些放在接口的方法 3.接口的原则 从许多方面来看,接口设计与用户界面设计相似。对于用户界面设计问题,需要考虑用 户想通过界面做什么,并且使用户非常简单地知道如何做他们想做的事,并且能通过界面去 做,而最后一步(做)是最重要的 不同之处在于,在进行用户界面设计时我们处理的是控件,像文本框和单选按钮,及它 们在一个或多个窗体上的布局。对于组件设计,我们处理的是属性和方法,以及它们对一个 或多个接口的影响,影响的接口越多,对客户就越有用。 就像用户界面设计,COM接口设计从某种意义上讲是一个基于经验的过程。也许为某 个项目采用一种方式设计,因为它适合这些客户:也许因为有特殊限制或技术上的可能而采 用另一种方式设计:不管采用哪种方式,其目的就是让客户满意
口中的一个方法。客户不必在运行期查询任何附加信息,只要有接口指针就能进行调用。接 口指针是一种指向可以调用的函数的数组的指针。 图14-5 虚拟方法表 属性就是函数 提供读写对象的数据 (或状态)的能力的接口方法叫做属性。下面讲述的方法与 C + +中的方 法类似,但与 V B中给出的例子不同。从语义的角度看它们是相同的, V B也是一种很好的工 具;但在实现时却不是,V B引入的封装层可能导致人们的误解。 • 只读属性等同于单个接口方法,该方法允许读取一个值。 • 只写属性等同于单个接口方法,该方法允许更新一个值。 • 读/写属性等同于两个接口方法,两个方法分别允许读取和更新一个值。 因此,如果有四个读/写属性, V B就会创建8个方法来读取和更新这四个值。 2. 接口的要素 一般来说,接口通常至少有一个方法,最多 1 0 2 4个( C O M和跨场所调度的限制导致的限 制),一个接口有多少方法是一个设计问题,这个问题是由程序员决定的,可以有一个或者多 个,但不是必须有,一个接口可以没有方法。通常一个设计得很好的接口的方法不超过 1 0到 1 5个。 没有方法的接口是不常见的,但也是有用的。它常用于提供组件和顾客间的一种秘密交 流或信号,就像你约好了一没见过面的人,约定他穿着一件特别的衣服,因而当你在人多的 场合遇见他时,能很快识别他。客户通过接口能检查确保组件是存在的。 这里的要素化指的是逻辑上把相关的方法一起放到一个接口,因此,如果我说 小心接口要素化,意思是你应当特别注意那些放在接口的方法。 3. 接口的原则 从许多方面来看,接口设计与用户界面设计相似。对于用户界面设计问题,需要考虑用 户想通过界面做什么,并且使用户非常简单地知道如何做他们想做的事,并且能通过界面去 做,而最后一步(做)是最重要的。 不同之处在于,在进行用户界面设计时我们处理的是控件,像文本框和单选按钮,及它 们在一个或多个窗体上的布局。对于组件设计,我们处理的是属性和方法,以及它们对一个 或多个接口的影响,影响的接口越多,对客户就越有用。 就像用户界面设计, C O M接口设计从某种意义上讲是一个基于经验的过程。也许为某一 个项目采用一种方式设计,因为它适合这些客户;也许因为有特殊限制或技术上的可能而采 用另一种方式设计;不管采用哪种方式,其目的就是让客户满意。 440计计ASP 3 高级编程 下载 组 件 客户
hinaopub.com 第4章cCOM.CoM+和sp441 下载 本书不可能对所遇到的每个问题都给出一套实际的接口设计大纲,但设计得好的接口有 一些共同特征: ·确保接口对使用者有用。COM有定义接口的能力,这些接口在语言上或者应用程序上 是不友好的,也就是说它们不能运行。当把COM设计成一种二进制标准时,一些语言 就比另一些语言功能更强,就像一些浏览器比其他浏览器功能更多一样。如果COM限 制这些语言,就不能得到广泛地使用,因此,必须认真考虑接口的性能。例如,一个主 要用于像ASP这样的脚本语言环境的组件,应当使用 Variant作为参数,并且参数能够输 入、修改和输出。这是脚本引擎的一个特征。因此,必须确保接口遵守这些原则并能在 这样的环境中正常工作 ·接口名称(或类模块)和方法名称采用描述性的名称。调用一个叫 IDoSomething接口和使 用一个叫Dolt的方法没什么意义,这些名称应该有意义,应尽可能说明它在客户的问题 中所完成的功能。 ·方法应当很好地要素化,逻辑相关,并不要有太多的方法。如果你已经有一个 IChannelselector的接口,它只应当含有与频道转换有关的方法。例如,如果需要 Fine Tune channel的方法,它应该包含在 I ChannelTuner接口中 属性相同。接口的属性应当与客户感兴趣的信息类型一致。 ·接口应当是强类型的。像VB和C++这些语言都是强类型的,也就是说我们所定义的变 量属于某一种类型,它只会有这种类型的数据,例如一个数(Long型或 Integer型),如果 有人想分配给该变量一个 String型数据,这时,编译器就会产生错误。ASP只支持像 Ⅴ SCript这样的弱类型脚本语言,在 SCript中,所有的变量都被定义为 Variant型,这 种类型的变量可以含有任何类型的数据。把接口定义为强类型的好处是使用时简单明了, 可以看到所使用的参数的类型,而不必猜测一个方法能处理什么数据类型。 ·喜欢使用自己的接口。这是一个全球所有成功的公司所遵循的金科玉律:使用自己的接 口,或者至少应该确信所使用的接口是个好接口。 4.接口的不变性 旦设计好一个COM接口,并且通过某些形式向客户发布了,这个接口就应当被认为是 不可变的,不能对其做任何可能影响其二进制表现的改动。 看一下 I Volume Control接口的描述,其中有 Increase Volume方法和 Decrease volume方法 如果发布了这个组件,而且人们把这个遥控组件用在他们的应用程序中,并使用了我们的接 口及其所有方法。如果我们再决定去掉 Decrease volume方法会怎么样呢?显然,那些应用程 序将被严重破坏,或者将会有一些非常烦人的相关问题,如果改变一个方法参数的数量或者 类型,也可能会产生同样的问题 因此,有一些原则需要遵守 在对一个接口满意前,不要发表他。 如果实在需要改变一个接口,不应修改已存在的这个接口,而是为所需的扩展功能再创 建一个接口。这当然要求客户类型支持多重接口,但ASP目前不支持多重接口 个接口一旦发布,就不能改变其中的任何一部分,这包括方法的顺序、参数类型等。 如果改变了一个已经存在的接口(我们推荐不要这样),应重新编译所有使用该接口的客 户应用程序。就像我们已经讲过的,使用早期绑定的客户将会把接口的设计硬编码为
本书不可能对所遇到的每个问题都给出一套实际的接口设计大纲,但设计得好的接口有 一些共同特征: • 确保接口对使用者有用。 C O M有定义接口的能力,这些接口在语言上或者应用程序上 是不友好的,也就是说它们不能运行。当把 C O M设计成一种二进制标准时,一些语言 就比另一些语言功能更强,就像一些浏览器比其他浏览器功能更多一样。如果 C O M限 制这些语言,就不能得到广泛地使用,因此,必须认真考虑接口的性能。例如,一个主 要用于像A S P这样的脚本语言环境的组件,应当使用 Va r i a n t作为参数,并且参数能够输 入、修改和输出。这是脚本引擎的一个特征。因此,必须确保接口遵守这些原则并能在 这样的环境中正常工作。 • 接口名称(或类模块)和方法名称采用描述性的名称。调用一个叫 I D o S o m e t h i n g接口和使 用一个叫D o I t的方法没什么意义,这些名称应该有意义,应尽可能说明它在客户的问题 中所完成的功能。 • 方法应当很好地要素化,逻辑相关,并不要有太多的方法。如果你已经有一个 ICh a n n e l S e l e c t o r的接口,它只应当含有与频道转换有关的方法。例如,如果需要一个 F i n e Tu n e C h a n n e l的方法,它应该包含在I C h a n n e l Tu n e r接口中。 • 属性相同。接口的属性应当与客户感兴趣的信息类型一致。 • 接口应当是强类型的。像 V B和C + +这些语言都是强类型的,也就是说我们所定义的变 量属于某一种类型,它只会有这种类型的数据,例如一个数 ( L o n g型或I n t e g e r型),如果 有人想分配给该变量一个 S t r i n g型数据,这时,编译器就会产生错误。 A S P只支持像 V B S c r i p t这样的弱类型脚本语言,在 V B S c r i p t中,所有的变量都被定义为 Va r i a n t型,这 种类型的变量可以含有任何类型的数据。把接口定义为强类型的好处是使用时简单明了, 可以看到所使用的参数的类型,而不必猜测一个方法能处理什么数据类型。 • 喜欢使用自己的接口。这是一个全球所有成功的公司所遵循的金科玉律:使用自己的接 口,或者至少应该确信所使用的接口是个好接口。 4. 接口的不变性 一旦设计好一个 C O M接口,并且通过某些形式向客户发布了,这个接口就应当被认为是 不可变的,不能对其做任何可能影响其二进制表现的改动。 看一下I Vo l u m e C o n t r o l接口的描述,其中有 I n c r e a s e Vo l u m e方法和D e c r e a s e Vo l u m e方法。 如果发布了这个组件,而且人们把这个遥控组件用在他们的应用程序中,并使用了我们的接 口及其所有方法。如果我们再决定去掉 D e c r e a s e Vo l u m e方法会怎么样呢?显然,那些应用程 序将被严重破坏,或者将会有一些非常烦人的相关问题,如果改变一个方法参数的数量或者 类型,也可能会产生同样的问题。 因此,有一些原则需要遵守: • 在对一个接口满意前,不要发表他。 • 如果实在需要改变一个接口,不应修改已存在的这个接口,而是为所需的扩展功能再创 建一个接口。这当然要求客户类型支持多重接口,但 A S P目前不支持多重接口。 • 一个接口一旦发布,就不能改变其中的任何一部分,这包括方法的顺序、参数类型等。 如果改变了一个已经存在的接口 (我们推荐不要这样 ),应重新编译所有使用该接口的客 户应用程序。就像我们已经讲过的,使用早期绑定的客户将会把接口的设计硬编码为 第1 4章 C O M、C O M +和A S P计计441 下载
442Asp3高程 China pub. coM 下载 EXE或DLL,因此,它们必须升级。 记住ⅤB隐藏了许多接口信息。因此,当修改或增加一个类模块的公用函数、子程序或 属性时,实际上就是在修改缺省接口,ⅤB会自动为一个 Activex项目中的每个公用类模 块创建和管理COM接口。 这些都是好的COM原则,但应用于ASP中的组件更具有灵活性,因为它们使用后期绑定 142.5| Unknown接口 前面说过每个COM组件都要实现一个叫 IUnknown的接口,这个接口在COM中起着极为 重要的作用,有两个作用 引用计数 通过询问支持的接口,动态地揭示接口功能。 I. Querylnterface QueryInterface是一个方法,通过该方法,可以在运行期动态显示和査询组件的功能。这 种方法接受一个接口标识符(ID,另一种类型的GUID),并且如果此接口被支持的话,就返回 被请求的接口,供发出请求的代码使用。 ◇在Ⅴ SCript中,使用Set关键字调用该方法,这就是查询组件是否支持这个IID代表的接 Set RemoteControl Createobject("TV. Remotecontrol') 2.对象的生存期和引用计数 COM允许传递一个接口指针到应用程序中,并且,当一个接口在使用时,不能破坏提供 指针的COM对象。这可以比作一个四方同时通话的电话会议:在会议结束前,电信局应当使 电话线保持连接 为了跟踪接口指针的使用和一个COM对象的生存期,我们使用引用计数。 当一个组件第一次由COM运行期创建时,它的“生命”就开始了,而且 IUnknown接口的 AddRef方法已经被组件自身隐式调用了。 AddRef方法的功能很简单,仅将组件引用计数器的 值增加1。引用计数器的初值为0,创建组件后,其引用计数器的值为1 每当 QueryInterface函数给顾客提供一个接口指针,就调用 AddRef方法将引用计数器的值 加1:相反地,当顾客使用接口完毕,就调用 Release方法,将引用计数器的值减1。如果引用 计数器的值达到0,那么对象就知道不再有顾客使用它了,这时,它就自我取消,结束其生存 期 COM对象必须能够可靠地管理自己的生存期 作为一个非常简单的概念,引用计数是一个强大的功能。然而,在像C++这样的语言中有 点麻烦,因为程序员必须记住手工调用 AddRef和 Release,如果调用不配对,对象就永远不会 被取消。在ⅤB和ASP中,从不直接调用 Add Ref和 Release,因此不存在调用不配对问题。 1426使用 Dispatch——后期绑 Dispatch是一个接口,COM使用它允许客户应用程序在运行期动态地发现和调用组件缺 省接口的方法。这一种调用组件功能的方式叫作后期绑定,因为在调用方法之前,组件必须
E X E或D L L,因此,它们必须升级。 • 记住V B隐藏了许多接口信息。因此,当修改或增加一个类模块的公用函数、子程序或 属性时,实际上就是在修改缺省接口, V B会自动为一个A c t i v e X项目中的每个公用类模 块创建和管理C O M接口。 这些都是好的C O M原则,但应用于A S P中的组件更具有灵活性,因为它们使用后期绑定。 14.2.5 IUnknown接口 前面说过每个 C O M组件都要实现一个叫 I U n k n o w n的接口,这个接口在 C O M中起着极为 重要的作用,有两个作用: • 引用计数。 • 通过询问支持的接口,动态地揭示接口功能。 1. QueryInterface Q u e r y I n t e r f a c e是一个方法,通过该方法,可以在运行期动态显示和查询组件的功能。这 种方法接受一个接口标识符 ( I I D,另一种类型的G U I D ),并且如果此接口被支持的话,就返回 被请求的接口,供发出请求的代码使用。 在V B S c r i p t中,使用S e t关键字调用该方法,这就是查询组件是否支持这个 I I D代表的接 口。 2. 对象的生存期和引用计数 C O M允许传递一个接口指针到应用程序中,并且,当一个接口在使用时,不能破坏提供 指针的C O M对象。这可以比作一个四方同时通话的电话会议:在会议结束前,电信局应当使 电话线保持连接。 为了跟踪接口指针的使用和一个 C O M对象的生存期,我们使用引用计数。 当一个组件第一次由C O M运行期创建时,它的“生命”就开始了,而且 I U n k n o w n接口的 A d d R e f方法已经被组件自身隐式调用了。 A d d R e f方法的功能很简单,仅将组件引用计数器的 值增加1。引用计数器的初值为0,创建组件后,其引用计数器的值为 1。 每当Q u e r y I n t e r f a c e函数给顾客提供一个接口指针,就调用 A d d R e f方法将引用计数器的值 加1;相反地,当顾客使用接口完毕,就调用 R e l e a s e方法,将引用计数器的值减 1。如果引用 计数器的值达到0,那么对象就知道不再有顾客使用它了,这时,它就自我取消,结束其生存 期。 C O M对象必须能够可靠地管理自己的生存期。 作为一个非常简单的概念,引用计数是一个强大的功能。然而,在像 C + +这样的语言中有 点麻烦,因为程序员必须记住手工调用 A d d R e f和R e l e a s e,如果调用不配对,对象就永远不会 被取消。在V B和A S P中,从不直接调用A d d R e f和R e l e a s e,因此不存在调用不配对问题。 14.2.6 使用I D i s p a t c h—后期绑定 I D i s p a t c h是一个接口,C O M使用它允许客户应用程序在运行期动态地发现和调用组件缺 省接口的方法。这一种调用组件功能的方式叫作后期绑定,因为在调用方法之前,组件必须 442计计ASP 3 高级编程 下载