Com对象的解释

本文详细介绍了COM组件,包括COM的概念、对象模型、实现方式、进程模型、可重用性等方面。COM是微软提出的组件标准,提供了一种语言无关的组件交互方式,确保了组件的可重用性和稳定性。COM对象通过接口提供服务,通过全局唯一标识符GUID进行标识,具有进程内和进程外两种进程模型。此外,文章还探讨了COM对象的创建、注册、内存管理和卸载过程,以及如何使用Visual C++开发COM应用。
摘要由CSDN通过智能技术生成
⊙ 第一章 概述
   COM 是什么
   COM 对象与接口
   COM 进程模型
   COM 可重用性
⊙ 第二章 COM 对象模型
   全局唯一标识符 GUID
   COM 对象
   COM 接口
   接口描述语言 IDL
   IUnknown 接口
   COM 对象的接口原则
⊙ 第三章 COM 的实现
   COM 组件注册信息
   注册 COM 组件
   类厂和 DllGetObjectClass 函数
   CoGetClassObject 函数
   CoCreateInstance / CoCreateInstanceEx 函数
   COM 库的初始化
   COM 库的内存管理
   组件程序的装载和卸载
   COM 库常用函数
   HRESULT 类型
⊙ 第四章 COM 特性
   可重用性:包容和聚合
   进程透明性 (待学)
   安全性 (待学)
   多线程特性 (待学)
⊙ 第五章 用 Visual C++ 开发 COM 应用
   Win32 SDK 提供的一些头文件的说明
   与 COM 接口有关的一些宏
===============================================================================


正 文
===============================================================================
⊙ 第一章 概述
===============================================================================
   COM 是什么
-------------------------------------------------------------------------------
COM 是由 Microsoft 提出的组件标准,它不仅定义了组件程序之间进行交互的标准,并且也提供了组件程序运行所需的环境。在 COM 标准中,一个组件程序也被称为一个模块,它可以是一个动态链接库,被称为进程内组件(in-process component);也可以是一个可执行程序(即 EXE 程序),被称作进程外组件(out-of-process component)。一个组件程序可以包含一个或多个组件对象,因为 COM 是以对象为基本单元的模型,所以在程序与程序之间进行通信时,通信的双方应该是组件对象,也叫做 COM 对象,而组件程序(或称作 COM 程序)是提供 COM 对象的代码载体。

COM 对象不同于一般面向对象语言(如 C++ 语言)中的对象概念,COM 对象是建立在二进制可执行代码级的基础上,而 C++ 等语言中的对象是建立在源代码级基础上的,因此 COM 对象是语言无关的。这一特性使用不同编程语言开发的组件对象进行交互成为可能。

-------------------------------------------------------------------------------
   COM 对象与接口
-------------------------------------------------------------------------------
类似于 C++ 中对象的概念,对象是某个类(class)的一个实例;而类则是一组相关的数据和功能组合在一起的一个定义。使用对象的应用(或另一个对象)称为客户,有时也称为对象的用户。

接口是一组逻辑上相关的函数集合,其函数也被称为接口成员函数。按照习惯,接口名常是以“I”为前缀。对象通过接口成员函数为客户提供各种形式的服务。

在 COM 模型中,对象本身对于客户来说是不可见的,客户请求服务时,只能通过接口进行。每一个接口都由一个 128 位的全局唯一标识符(GUID,Global Unique Identifier)来标识。客户通过 GUID 来获得接口的指针,再通过接口指针,客户就可以调用其相应的成员函数。
与接口类似,每个组件也用一个 128 位 GUID 来标识,称为 CLSID(class identifer,类标识符或类 ID),用 CLSID 标识对象可以保证(概率意义上)在全球范围内的唯一性。实际上,客户成功地创建对象后,它得到的是一个指向对象某个接口的指针,因为 COM 对象至少实现一个接口(没有接口的 COM 对象是没有意义的),所以客户就可以调用该接口提供的所有服务。根据 COM 规范,一个 COM 对象如果实现了多个接口,则可以从某个接口得到该对象的任意其他接口。从这个过程我们也可以看出,客户与 COM 对象只通过接口打交道,对象对于客户来说只是一组接口。

-------------------------------------------------------------------------------
   COM 进程模型
-------------------------------------------------------------------------------
COM 所提供的服务组件对象在实现时有两种进程模型:进程内对象和进程外对象。如果是进程内对象,则它在客户进程空间中运行;如果是进程外对象,则它运行在同机器上的另一个进程空间或者在远程机器的空间。

进程内服务程序:
服务程序被加载到客户的进程空间,在 Windows 环境下,通常服务程序的代码以动态连接库(DLL)的形式实现。

本地服务程序:
服务程序与客户程序运行在同一台机器上,服务程序是一个独立的应用程序,通常它是一个 EXE 文件。

远程服务程序:
服务程序运行在与客户不同的机器上,它既可以是一个 DLL 模块,也可以是一个 EXE 文件。如果远程服务程序是以 DLL 形式实现的话,则远程机器会创建一个代理进程。

虽然 COM 对象有不同的进程模型,但这种区别对于客户程序来说是透明的,因此客户程序在使用组件对象时可以不管这种区别的存在,只要遵照 COM 规范即可。然而,在实现 COM 对象时,还是应该慎重选择进程模型。进程内模型的优点是效率高,但组件不稳定会引起客户进程崩溃,因此组件可能会危及客户;(savetime 注:这里有点问题,如果组件不稳定,进程外模型也同样会出问题,可能是因为进程内组件和客户同处一个地址空间,出现冲突的可能性比较大?)进程外模型的优点是稳定性好,组件进程不会危及客户程序,一个组件进程可以为多个客户进程提供服务,但进程外组件开销大,而且调用效率相对低一点。

-------------------------------------------------------------------------------
   COM 可重用性
-------------------------------------------------------------------------------
由于 COM 标准是建立在二进制代码级的,因此 COM 对象的可重用性与一般的面向对象语言如 C++ 中对象的重用过程不同。对于 COM 对象的客户程序来说,它只是通过接口使用对象提供的服务,它并不知道对象内部的实现过程,因此,组件对象的重用性可建立在组件对象的行为方式上,而不是具体实现上,这是建立重用的关键。COM 用两种机制实现对象的重用。我们假定有两个 COM 对象,对象1 希望能重用对象2 的功能,我们把对象1 称为外部对象,对象2 称为内部对象。

(1)包容方式。
对象1 包含了对象2,当对象1 需要用到对象2 的功能时,它可以简单地把实现交给对象2 来完成,虽然对象1 和对象2 支持同样的接口,但对象1 在实现接口时实际上调用了对象2 的实现。

(2)聚合方式。
对象1 只需简单地把对象2 的接口递交给客户即可,对象1 并没有实现对象2 的接口,但它把对象2 的接口也暴露给客户程序,而客户程序并不知道内部对象2 的存在。

===============================================================================
⊙ 第二章 COM 对象模型
===============================================================================
   全局唯一标识符 GUID
-------------------------------------------------------------------------------
COM 规范采用了 128 位全局唯一标识符 GUID 来标识对象和接口,这是一个随机数,并不需要专门机构进行分配和管理。因为 GUID 是个随机数,所以并不绝对保证唯一性,但发生标识符相重的可能性非常小。从理论上讲,如果一台机器每秒产生 10000000 个 GUID,则可以保证(概率意义上)的 3240 年不重复)。

GUID 在 C/C++ 中可以用这样的结构来描述:

  typedef struct _GUID
      {
      DWORD Data1;
      WORD  Data2;
      WORD  Data3;
      BYTE  Data4[8];
      } GUID;

例:{64BF4372-1007-B0AA-444553540000} 可以如下定义一个 GUID:

  extern "C" const GUID CLSID_MYSPELLCHECKER =
      { 0x54BF0093, 0x1048, 0x399D,
      { 0xB0, 0xA3, 0x45, 0x33, 0x43, 0x9
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值