概要
本文介绍了COM编程发展过程中的一些简单原则。对那些对COM一无所知的初学者来说我觉得会有所帮助。这篇入门简单和轻松,我觉得...
通过大多数的商业性的经典面向对象设计,COM被证明是设计软件的一种务实的方法。如果你是Windows平台上开发人员,不清楚COM是不可想象的。
COM基本特点
- COM是一个规范。它描述了创建组件(Component)是你需要遵循的规范。
- COM是面向对象的。每个COM对象有自己的特征和状态。
- COM对象是黑盒对象。
- COM对象可以动态链接。就像你电脑上的即插即用设备一样。:插上就可以开始工作。不需要的时候在拔掉。
- COM使你能够创建分布式应用。你调用COM的时候甚至不需要知道COM对象在哪。它甚至可以宿主在远程主机上。
- 任何支持函数指针的语言都可以编写COM应用。
- COM组件是版本独立的。这意味着当你升级一个已有组件时,它被认为是同一个组件的另一个版本。这样可以避免旧客户端的版本冲突。
- COM组件可以实现代码复用。一旦创建了COM组件,它就可以在任何项目中无限次使用。
组件的类型
- In-process(进程内组件): 它们都是DLL(动态链接库)形式。它们在应用程序的内存中运行(所以叫它们进程内组件)。因为它们和应用程序使用同一的内存空间,如果它们崩溃了,会导致整个应用程序崩溃。
- Out-process(进程外组件):它们都是EXE形式。他们运行在不同于客户端程序的内存中(所以叫他们进程外组件).因为和应用程序使用不同的内存空间,如果组件崩溃了,并不会影响应用程序。
- Remote(远程组件): 远程组件和其他组件没有两样,除了它是通过网络运行在远程机器上。它们用DCOM(分布式COM)实现。
其他...
COM组件有一个唯一标志号。它们保存在注册表的HKEY_CLASSES_ROOT主键中。像我刚才讲的,COM不只是一个文档的规范。它包含许多API,还有一些操作系统级别的代码。这些都体现在COM运行库中。
COM组件库本身是一个系统组件(一般都集成在操作系统中),使得不同组件可以在进程中(In-process)、进程外(Out-process)或远程组件(remote)相互调用。
创建的COM组件都高度封装。当创建了组件并发布,客户端只能调用但看不到实现代码。甚至不能访问你类中的代码。
就像我刚才解释的,COM组件是黑盒组件。尽快它是可重用的组件,但不是像面向对象语言那样的复用。COM组件可以包含其他COM组件,并且可以把对特定接口的实现委托其他COM组件。但是你不能像在C++中继承类一样集成COM对象。
这是不是一种客户端通过使用组件来访问服务的方式?嘿,这就是接口的概念。每个组件都有一个必须实现的接口。这个接口不实现任何方法:方法是在Co-Class(组件类)中实现。接口之包含对方法的声明。接口是客户端访问组件服务的唯一方式。
现在接口是通过VTables实现的。VTable包含一个指针数组。这些指针顺序指向组件的函数。当你用代码创建了组件的一个对象时,你同时也创建了它在内存中的VTable。
所有COM对象都实现IUnknown这个特点的接口。通过这个接口,可以得到对COM对象其他接口的信息。
客户端创建一个接口的指针。这个指针指向一个虚拟指针。这个虚拟指针指向VTable。使用接口指针和虚拟指针,客户端可以使用组件的任何函数。
接口主要有两种:
- 标准接口:标准接口是COM库提供的。
IUnknown, IDispatch, IClassFactory, IOle, IDataObject, IStream 和 IStorage是其中的一些。 - 自定义接口:这些是自己创建的接口。
组件识别
由于组件是在全球范围内开发和使用,所以我们必须能够识别每个组件。你觉得现在是怎么解决的?其实,开源软件组织(Open Software Foundation - OSF)解决了这个问题,他们开发了一种算法可以生成一个唯一标志符,称为UUID(Universal Unique Identifier)。在COM中,它们被称为GUID(Global Unique Identifie)。GUID是一个数字,分配给每个接口、类或者库。
COM组件通过GUID来区分每个对象。它们是128位在统计学上唯一的的数字。如果GUID是通过工具或者函数生成的,则程序员不用担心会和其他人重复。
We wont get too much into the details of how this algorithm works, but let me tell you the aspects it takes into consideration when it generates that unique identifier:
我们不需要知道这个算法具体如何工作,但是我可以告诉你一些在生成GUID的算法考虑的因素:
每个COM对象都有了一GUID后,这些GUID都保存在哪里?它们保持在注册表中。所有COM类都注册在HKEY_CLASSES_ROOT\CLSID下。每个CLSID,都有一个子健为InProcServer32。它的值就是这个类相关的DLL的文件名。
组件创建后,它的形式为一个EXE或者一个DLL。使用前必须注册它们。如果是发布一个组件,它可以在安装的过程中后台自动完成。你也可以手动注册。
使用下面的命令可以注册DLL(动态链接库):
REGSVR32 <name of Your COM DLL >
使用下面的命令注册EXE(可执行的程序):
<COM exe name > /REGSERVER
这篇文章,就某些方面我解释了COM的基础和基本原理。不管你有什么建议(无论好坏),尽管联系我。
版权
这篇文章没有显式的附件版权,但是文章正文或者下载的文件中可有包含有使用条款。如果有疑问可以使用下面的讨论版联系作者。
作者介绍
Renjith Ramachandran  | Renjith很酷而且单纯,他来自kerala, 硬件设计师、程序员兼做新技术研究。 他对开源软件异常热爱,参与了Mozilla Firefox的工作。 喜欢听音乐,喜欢踢足球和看足球比赛,喜欢在长途自驾时听音乐。 他是INDIAN IT FORUM - www.indianITforum.com - 印度最大的IT专业论坛 - 的创立者。 最近他在研究以前优秀Unix中的东西,因为他的客户有进一步这方面的需求。 | 职位: | 架构师 | | 国家: | 印度 | |