COM,即组件对象模型,是关于如何建立组件以及如何通过组件建立应用程序的一个规范,说明了如何可动态交替更新组件。

1、使用组件的优点:

    组件架构的一个优点就是应用可以随时间的流逝而发展进化。除此之外,使用组件还有一些可以使对已有应用升级更加方便和灵活的优点,如应用的定制,组件库以及分布式组件等

   使用组件的种种优点直接来源于可以将它们动态的插入或卸出应用。为了实现这种功能,所有的组件必须满足两个条件:

   第一,组件必须动态链接;

   第二,它们必须隐藏(或封装)其内部实现细节。动态链接对于组件而言是一个至关重要的要求,而消息隐藏则是动态链接的一个必要条件。

COM组件由以Win 32动态连接库(DLL)或可执行文件(EXE)形式发布的可执行代码所组成。遵循COM规范编写出来的组件将能够满足对组件架构的所有要求。COM组件可以给应用程序、操作系统以及其他组件提供服务;自定义的COM组件可以在运行时刻同其他组件连接起来构成某个应用程序;COM组件可以动态的插入或卸出应用。

2、如何注册com组件?

    有两种方式注册组件:
   一种是调用regsvr32.exe:
   例如我们运行regsvr32.exe c:\test.dll来注册位于C:盘根目录下的test.dll。
   另外一种是在MTS(微软事务服务器)中注册。MTS是值得推荐的,因为它具有下列优点:

1)、动态卸载平衡,提高组件和基于组件的应用程序的升级性。
2)、包含公布和提交事件和队列组件的能力,使得更容易与多个组件联合。

3、com组件与注册表的关系? 

COM的重要性质之一是位置透明性。相对而言,以往在调用普通动态链接库中的输出函数时,必须要将此动态链接库放到应用程序的同级目录下(或系统可以找得到的目录下,如Windows目录、环境中已有的搜索路径等),或将动态库的位置信息硬编码到程序中的做法,其实都说明了普通动态库的位置不透明性。

当客户程序调用COM对象时,会更轻松一些,因为调用方不需要考虑COM组件所处的位置,不论它在哪个目录下,或是否在当前工作站上,一切都由系统提供的机制来保障对COM对象的定位,这就是位置无关性。

其实,COM位置无关性的实现机制并不深奥,它主要依赖于注册表,这也就是为什么一定要在使用之前对COM组件进行注册的原因。COM库在接到客户程序的请求后,会到注册表中检索COM对象的注册条目,并以此来定位COM对象。

对于COM对象,如要使之能够成功地被COM库定位,则需要至少在注册表中写入如图12所示的信息。

观察这两个注册信息,可以发现它们之间是有联系的。现在在注册表的HKEY_ CLASSES_ROOT\键中增加了一个注册项{18034D20-B0C3-4135-9DCF-C2E12A58D330},这个GUID正是CLSID,代表COM类。



组件的ProgID注册

 

组件的CLSID信息注册

在这个注册项目下,有一个名为InProcServer32的字符串值,它代表容纳此COM 类的载体应当是一个动态链接库。这个字符串值的数据是“xxx.dll”,指明了组件所处的物理位置,这个信息对COM库查找和定位组件起到了决定性的作用。

下面还有一个名为ProgID的字符串值,其内容是MyCOM.SimpleMath.1ProgID的出现主要是为了给长长的CLSID起一个人性化的名称,通常在客户程序中使用ProgID代替CLSID

另外,也可以使用ProgID在注册表中对COM对象进行标识,在图2中显示的信息就是组件ProgID的注册信息,其中一个名为CLSID字符串值的数据就是COM对象的CLSID值,所以,无论根据ProgIDCLSID,都可以定位到指定组件。

当然,COM组件不能天生就具备将注册信息写入到注册表中的功能,对进程内服务器而言,还必须实现两个名为DllRegisterServerDllUnregisterServer的输出函数,来负责注册信息的写入和卸载。

HRESULT DllRegisterServer(void)

{

// 主要实现方法:

// 调用Windows API函数得到模块当前所在的物理位置,

// 调用Windows API操作注册表的函数创建图5-45-5中所示的注册项目

…(代码略)

}

HRESULT DllUnregisterServer(void)

{

// 主要实现方法

// 调用Windows API操作注册表的函数,在注册表中删除写入的信息。

(代码略)

}