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是值得推荐的,因为它具有下列优点:
2)、包含公布和提交事件和队列组件的能力,使得更容易与多个组件联合。
3、com组件与注册表的关系?
COM的重要性质之一是位置透明性。相对而言,以往在调用普通动态链接库中的输出函数时,必须要将此动态链接库放到应用程序的同级目录下(或系统可以找得到的目录下,如Windows目录、环境中已有的搜索路径等),或将动态库的位置信息硬编码到程序中的做法,其实都说明了普通动态库的位置不透明性。
当客户程序调用COM对象时,会更轻松一些,因为调用方不需要考虑COM组件所处的位置,不论它在哪个目录下,或是否在当前工作站上,一切都由系统提供的机制来保障对COM对象的定位,这就是位置无关性。
其实,COM位置无关性的实现机制并不深奥,它主要依赖于注册表,这也就是为什么一定要在使用之前对COM组件进行注册的原因。COM库在接到客户程序的请求后,会到注册表中检索COM对象的注册条目,并以此来定位COM对象。
对于COM对象,如要使之能够成功地被COM库定位,则需要至少在注册表中写入如图1和2所示的信息。
观察这两个注册信息,可以发现它们之间是有联系的。现在在注册表的HKEY_ CLASSES_ROOT\键中增加了一个注册项{18034D20-B0C3-4135-9DCF-C2E12A58D330},这个GUID正是CLSID,代表COM类。
图1 组件的ProgID注册
图2 组件的CLSID信息注册
在这个注册项目下,有一个名为InProcServer32的字符串值,它代表容纳此COM 类的载体应当是一个动态链接库。这个字符串值的数据是“xxx.dll”,指明了组件所处的物理位置,这个信息对COM库查找和定位组件起到了决定性的作用。
下面还有一个名为ProgID的字符串值,其内容是MyCOM.SimpleMath.1。ProgID的出现主要是为了给长长的CLSID起一个“人性化”的名称,通常在客户程序中使用ProgID代替CLSID。
另外,也可以使用ProgID在注册表中对COM对象进行标识,在图2中显示的信息就是组件ProgID的注册信息,其中一个名为CLSID字符串值的数据就是COM对象的CLSID值,所以,无论根据ProgID或CLSID,都可以定位到指定组件。
当然,COM组件不能天生就具备将注册信息写入到注册表中的功能,对进程内服务器而言,还必须实现两个名为DllRegisterServer和DllUnregisterServer的输出函数,来负责注册信息的写入和卸载。
HRESULT DllRegisterServer(void)
{
// 主要实现方法:
// 调用Windows API函数得到模块当前所在的物理位置,
// 调用Windows API操作注册表的函数创建图5-4、5-5中所示的注册项目
…(代码略)
}
HRESULT DllUnregisterServer(void)
{
// 主要实现方法
// 调用Windows API操作注册表的函数,在注册表中删除写入的信息。
(代码略)
}