COM与DCOM技术
随着软件工业技术的迅速发展,传统的程序升级已经无法满足技术的发展需要,而且程序升级需要大量人力成本,解决这一问题的方法就是将应用程序分割成一些小的应用或组件,然后将这些组件在运行时组装起来以形成所需的应用程序,每一个组件都可以在不影响其他组件的情况下被升级。目前,在组件技术规范方面,主要有两个标准:一个是由对象管理组织(Object Management Group,OMG)起草并颁布的公共对象请求代理体系结构(Common Object Request Breaker Architecture,CORBA);另一个是由微软推出的组件对象模型(COM)技术。COM技术是在微软公司的对象链接与嵌入技术(OLE)上发展的,该技术提供了各个软件部件以标准模式在一起工作的框架和技术规范,此规范提供了为保证能够互操作、客户和组件应遵循的一些二进制和网络标准。在这种标准下,任意两个组件之间可以在不同的操作环境下进行通信,甚至使用不同的开发语言开发的组件也能实现。COM是一种软件组件间相互数据交换的有效方法。
组件实际上是一些小的二进制可执行程序。它可以给应用程序、操作系统,以及其他组件提供一些服务。多个COM对象可以连接起来以形成应用程序或组件系统,每一个应用程序都可划分为多个独立的模块进行开发,这里的每一个独立模块都是一个自给自足的组件。可以采取不同的开发语言去设计每一个组件。在运行时将这些组件通过接口组装起来以形成所需要的应用程序。
COM接口是COM规范中最重要的部分
,COM规范的核心内容就是对接口的定义,COM都是以接口的形式出现。组件与组件之间、组件与客户程序之间都要通过接口进行交互。接口成员函数将负责为客户或其他组件提供服务。对于COM来说,接口是一个包含一个函数指针数组的内存结构。每一个数组元素包含的是一个由组件所实现的函数的地址。对于COM而言,接口就是组件内存结构。对于客户来说,一个组件就是一个接口集,任何一个具备相同接口的组件都可对此组件进行相对于其他组件透明的替换。只要接口不发生变化,就可以在不影响整个由组件构成的系统的情况下自由的更换组件。COM接口的内存结构同C++编译器为抽象基类所生成的内存结构是相同的,因此可以合用抽象基类来定义COM接口。
COM接口的名字以字母I开头。COM组件有两个最基本的接口类,分别是Iunknown和IDispatch。
(1)所有的COM接口都必须继承一个名为IUnknown的接口,COM的核心接口是IUnknown接口。
客户在组件之间的通信是通过接口来实现的。组件可以不提供其他接口,但是必须提供IUnknown接口,其原因在于IUnkown接口提供了两个非常重要的特性:生存期控制和接口查询。IUnknown接口提供有成员函数QueryInterface()、AddRef()和Release(),分别用于查询组件中的其他接口和进行生存期控制。由于任何COM接口都是从IUnknown接口派生。因此在所有COM接口的虚拟函数表中保存的前3个成员函数指针一定是指向QueryInterface()、AddRef()和Release()的指针。这样,任何一个COM接口都可以被当作IUnknown接口来处理。在创建组件时,客户可以通过CreateInstance()函数得到IUnknown接口指针。
(2)Idispateh为调度接口
。调度接口把每一个函数每一个属性都编上号。客户程序要调用这些函数属性时,把这些编号传给IDispatch接口就行了,IDispatch再根据这些编号调用相应的函数。为了使编写者在设计和维护程序时方便,也为了使用者容易学习、记忆和调用,COM还支持用户自定义接口。
在COM规范中并没有对COM对象进行严格的定义,但COM提供的是面向对象的组件模型,COM组件提供给客户的是以对象形式封装起来的实体,客户程序与COM组件程序进行交互的实体是COM对象,类似如C++语言中类(Class)的概念。COM对象也包含属性(状态)和方法(操作),对象的状态反映了对象的客户存在,也是区别于其他对象的要素,而对象所提供的函数就是对象提供给外界的接口,客户必须通过接口才能获得对象的服务。对于COM对象来说,接口是它与外界交互的唯一途径,因此,封装特性也是COM对象的基本特征。在COM模型中,对象本身对于客户来说是不可见的,客户请求服务时只能通过接口进行,每个COM对象是用一个128位的全局唯一标识符(Globally Unique Identifier,GUID)来标识的,称为CLSID(class identifier类标识和类ID)。由于GUID是一个随机数,所以并不绝对保证唯一性,但发生标识符相重的可能性非常小。GUID的随机性由两方面特性保证:一方面是空间,对于网络中的计算机,通常取网络适配器的地址位,没有网络适配器的机器用其他随机数生成算法产生;另一方面是时间位,同一机器在不同时候产生的标识符总不相同。CLSID是用来标识COM对象的GUID,因此,CLSID在结构上与GUID一致。
COM规范采用开放软件基金会(Open Software Foundation,OSF)的分布式计算环境(Distributed Computing Environment,DCE)规范的描述远程调用接口描述语言(Interface Description Language,IDL)的基础上,进行扩展形成了COM接口的描述语言。接口描述语言提供了一种不依赖于任何语言的接口描述方法,因此,它可以成为组件程序和客户程序之间的共同语言。
分布式组件对象模型(Distributed COM,DCOM)是COM的网络扩展,它建立在COM之上,并且提供了一种使COM组件加入网络环境的透明网络协议,使COM对象能像在本机上一样在网络上彼此交互。DCOM技术的核心是地址透明性,它依赖对象远程过程调用(Object Remote Procedure Call,ORPC)来完成它所有的网络通信工作,使DCOM组件不仅能跨越进程边界,而且能跨越计算机间的物理边界而相互交换信息,程序员不必编写网络通信所需要的繁杂代码。在分布式计算机环境下,DCOM服务器和客户处于不同的地址空间,不能直接交互信息,客户和DCOM服务器通过代理(proxy)对象和存根(stub)模块间接地交互。
在Windows系统平台上,COM组件表现为一个DLL文件或exe可执行文件。一个组件程序可以包含一个或多个COM对象,并且每个COM对象可以实现多个接口。当其他组件或其客户程序调用组件的功能时,它首先创建一个COM对象或通过其他途径获得COM对象,然后通过对象所实现的COM接口调用其所提供的服务。当所有的服务结束后,如果客户程序不再需要该COM对象,那么它就应该释放该对象所占用的资源,包括对象本身。