您现在的位置是: 软件 > 开发者网络 > 技术跟踪 > 技术理论 > 正文


-Win xp中的多种网络
-试验试验试验试验
-用Freehand实现位图矢量化
-网络电话面面观

分布式组件对象模型DCOM揭秘
2001-07-24· ·QQ新人类编译··yesky

上一页  1 2 3 4  


  名字的唯一性

  COM接口的名字是唯一的。这就是说,编程者如果访问某个名字的接口,他可以认为在实现接口的所有COM对象中,该接口的成员函数和参数都将是完全一样的。因此,在我们上面的例子中,称为“驾驶”和“收音机”的接口,在任何实现它们的COM对象中,都将拥有完全一样的成员函数。如果你想要改变一个接口的成员函数,你必须用一个新的名字创建一个新接口。

  所有接口的源头--IUnknown

  通常介绍COM都是从讲述IUnknown接口开始的。IUnknown是所有COM接口的基础。虽然它挺重要,不过就算你不了解IUnknown,你也可以明白接口的概念。IUnknown的实现被更高级别的抽象隐藏起来,我们也使用这些抽象来建立自己的COM对象。不过,太过关注IUnknown将会令你感到迷惑。我们将从一个更高的级别来处理它,从而令你更容易理解它的概念。

  IUnknown类似C++中的抽象基类。所有的COM接口必须由IUnknown继承而来。IUnknown处理接口的创建和管理。IUnknown的方法被用来创建、引用计数和释放一个COM对象。所有的COM接口都实现这3个方法,它们被COM内部使用来管理接口。你可能从来不会自己调用这3个方法。

  一个典型的COM对象

  现在我们要将这些新的概念放在一起,并且介绍一个典型的COM对象和一个要访问该对象的程序。

  想象一下,如果你要创建一个最简单的COM对象。这个对象支持一个单一的接口,并且该接口只含有一个单一的函数。这个函数的功能也很简单--只是发出beep声。当一个编程者创建该COM对象,并且调用该对象支持的单一接口中的成员函数时,COM对象存在的机器将会发出beep声。更进一步的是,你要在一台机器上运行这个COM对象,但是从网络上的另一台机器来调用它。

  为了创建这个简单的COM对象,你必须做以下的事情:

  。你必须创建该COM对象,并且给它一个名字。该对象将会在一个相关的COM服务器中实现

  。你需要定义该接口并且给它起一个名字

  。你需要定义接口中的函数并且给它起一个名字

  。你将需要安装COM服务器

  在这个例子中,我将该COM对象称为Beeper,接口为IBeep,函数为Beep。你首先要马上面对的一个问题是命名这些对象,事实上,所有的机器都支持多个COM服务器,每个都可包含有一个或者多个COM对象,而每个COM对象都要实现一个或者多个的接口。这些服务器是经由不同的编程者创建的,这样就有可能选择一样的名字。同样,COM对象有一个或者多个的命名接口,它们同样是由多个编程者随意创建的,这样也有同名的问题。因此,我们必须要想个方法来防止名字的冲突。一个称为GUID(Globally Unique IDentifier,全球唯一标识器)的方法可解决这个问题。

  如何做到唯一--GUID

  要确保一个名字是唯一的,仅有两个方法:

  1。通过一些准政府组织来登记名字;

  2。使用一个特别的算法来产生唯一的数字,这些数字可被认为在世界范围内是唯一的

  第一个方法与网络上的域名管理一样。它的问题是你必须付$50来登记一个新的名字,而且要令登记生效,你要等几个星期。

  第二个方法对于开发者更为方便。如果你可以发明一个算法,每次人们调用它都可以产生一个可被认为是唯一的名字,那么这个问题就解决了。事实上,这个问题已经被开放软件基金会提到(Open Software Foundation,OSF)。OSF有一个算法,可将一个网络地址、时间(100纳秒递增)和一个计数器结合,得到一个128位的唯一数字。

  2的128次方是一个非常大的数字。通过它,你可以识别由宇宙开始到现在的每个100纳秒--而且还会剩下39位。OSF将它称为UUID,意思是Universally Unique Identifier,在COM的命名标准上,微软使用同样的算法。在COM中微软将它重命名为Globally Unique Identifier。

  GUID的记录通常采用16进制。不过这没有关系,一个典型的GUID类似为:

   "50709330-F93A-11D0-BCE4-204C4F4F5020"

  由于在C++中并没有标准的128位数据类型。,因此我们使用一个结构体来表示。虽然GUID的结构体包含有4个不同的字段,不过你可能从来不会操作它的成员。该结构体通常都作为一个整体使用。

typedef struct _GUID
{
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID;

  GUID的普通读音是“gwid”,与“squid”的发音类似。一些人也读为“goo-wid”。

  GUID通过一个称为GUIDGEN的程序产生。在GUIDGEN中,你只要按下一个按钮就可以产生一个新的GUID。你可以认为你产生的每个GUID都是唯一的,不管你产生了多少个,或者世界上有多少人产生它。这个认定可以成立是基于以下的原因:Internet上的所有机器都有一个唯一的地址。因此,你的机器最好是处在网络上。不过,即使你没有网络地址,GUIDGEN也将会产生一个,但是这样就会令唯一性的机率降低。

  COM对象和COM接口都有一个GUID来标识自己。因此我们为该对象选用的名字“Beeper”是没有关系的。对象是通过它的GUID来命名的。我们将该对象的GUID称为它的class ID。然后我们就可以使用一个#defind或者一个常数来令Beeper的名字和该GUID相关,这样我们就无需在代码中都使用这个128位的值。同样接口也将拥有一个GUID。要注意的是许多由不同的编程者来创建的不同COM对象将支持同样的IBeep接口,而它们都将全部使用同样的GUID来命名它。如果没有同样的GUID,COM就认为这是一个不同的接口。GUID就是它的名字。

  一个COM服务器

  COM服务器就是实现COM接口和类的程序。COM服务器有三个基本的配置。

  。进程中或者DLL服务器

  。Stand-alone EXE服务器

  。基于Windows NT的服务

  COM对象都是一样的,与服务器的类型无关。COM接口和coclasses将不会关心当前使用的服务器类型。对于客户端程序来说,服务器的类型几乎是完全透明的。不过对于写真正的服务器端来说,每种配置都将会有明显的不同:

  进程中的服务器是作为动态连接库(DLL)实现的。这意味着该服务器在运行时被动态地放进你的进程中

  COM服务器将成为你应用中的一部分,而COM操作在应用的线程中进行。事实上,许多的COM对象都是以这种方式实现的,因为性能很好--一个COM函数调用的系统开销很小,但你可以得到COM所有的设计和重用的好处

  COM自动处理载入和卸下该DLL

  一个进程外的服务器令客户和服务端的区分更明显。该类服务器作为一个独立的可执行(EXE)程序运行,因此处在一个私有的进程空间中。EXE服务器的启动和停止在Windows中服务管理器中进行(SCM)。COM接口的调用通过内部的进程通信技术来处理。服务器可以运行在本地的机器,或者在一个远程的计算机上。如果服务器在一个远程的计算机上,我们称它为“Distributed COM,分布式的COM”,或者DCOM。

  Windows NT提出了一个服务的概念。一个服务是指该程序由Windows NT自动管理,与桌面的用户无关。这意味着服务可以在启动时自动开始,并且即使是没有人登录到Windows NT中,也可以自动运行。服务提供了一个极好的方法来运行COM服务器应用。

  还有第四种的服务器,称为“surrogate”,这是一个可允许进程中的服务器在远程运行的程序。对于要建立一个可通过网络访问的基于DLL的COM服务器,surrogate是很有用的。

  客户端和服务器端的交互

  在COM中,客户端程序驱动所有的事情。服务器是被动的,只响应客户的请求。这意味着对于客户的个别方法调用,COM服务器以一个同步的方式运作

  。客户端的程序启动服务器

  。客户端请求COM对象和接口

  。客户端发起所有的方法调用到服务器

  。客户端释放服务器的接口,允许服务器关闭

  这个区别是重要的。有各种不同的方法可模拟服务器到客户的调用,不过它们都难以实现,并且都相当复杂(这个被称为回叫)。通常没有客户的请求,服务器不做任何的事情。

  以下就是COM客户和服务器之间的一个典型的交互

  客户请求

  请求访问一个特别的COM接口,特别的COM类和接口(通过GUID)

  服务器响应

  。启动服务器(如果需要)。如果是一个进程内的服务器,DLL将被载入。可执行的服务器将由SCM运行

  。创建请求的COM对象

  。创建到COM对象的一个接口

  。增加激活接口的引用计数

  。返回该接口给客户

  客户请求

  调用接口的一个方法

  服务器响应

  执行一个COM对象的方法

  客户请求

  释放接口

  服务器响应

  减少接口引用的数目

  如果引用计数为0,将会删除该COM对象

  如果没有活动的连接,关闭服务器。某些服务器不会关闭自身

  如果你要了解COM,你必须使用一个以客户为中心的方法

  三、总结

  我们尝试从几个不同的方面来了解COM。C++是COM的原始语言,不过重要的是我们要了解它们的不同。COM有许多类似C++的地方,不过它也有很大的不同。在客户和服务器间通信方面,COM提供了一个全新的方式。

  接口是COM最为重要的概念之一。所有的COM交互都经由接口进行。由于在C++中,并没有一个直接与接口对应的事物,因此有点难以掌握。我们还介绍了GUID的概念。GUID在COM中是普遍存在的,并且提供了一个极好的方式来在一个大型网络中标识一个实体。

  COM服务器是传送COM组件的媒介。所有的事情都集中在传送COM组件到一个客户应用上。在以下的章节中,我们将创建一个简单的客户和服务器应用来解释这些概念。


上一页  1 2 3 4  

【责任编辑:方舟】
【发表评论】【关闭窗口】
■ 相关内容
 微软事务处理服务介绍
 关于Plug-In实现的描述
 关于Plug-In实现的描述
 DCOM揭秘之六
 DCOM揭秘之五
 DCOM揭秘之三
 C++子对象和堆对象
 DCOM揭秘之二
 C++语法之函数重载
 初识Visual C++.NET开发环境
感谢 访问天极网,如果您觉得该文章涉及版权问题,请看这里!