组件对象模型

一、概述

1.组件对象模型 (COM) 是 Microsoft 于 1993 年推出的软件组件二进制接口标准
2.它的用途是:在大量编程语言中,创建进程间通信对象
3.COM 是其他 Microsoft 技术和框架的基础,包括 OLE、OLE 自动化、Browser Helper Object、ActiveX、COM+、DCOM、Windows shell、DirectX、UMDF 和 Windows Runtime。
4.COM 的本质是一种实现对象语言中立方式,这些对象可以在不同于创建对象的环境中使用,甚至可以跨越机器边界。【译者注:COM 的本质是,创建和使用与编程语言无关的对象,并且在不同环境中使用,甚至在不同的机器上使用】
5.复用性:对于编写良好的组件,COM 允许在不了解其内部实现的情况下重用对象,因为它迫使组件实现者提供“与实现分离的”定义良好的接口。
6.“语言的不同分配语义”是通过“引用计数”“使对象负责自己的创建和销毁”来适应的。【译者注:语言的不同分配语义,是指不同编程语言对内存的分配和回收的那一部分语义。通俗地讲,通过“引用计数(reference-counting)”,对象实现自己的 new() 和 销毁】
7.对象不同接口之间的类型转换是通过QueryInterface方法实现的。
8.COM 中“继承”的首选方法是创建方法“调用”被委托给的子对象【译者注:父对象的方法“调用”被委托给子对象】。
9.COM 是一种接口技术,仅在 Microsoft Windows 和 “Apple 的 Core Foundation 1.3 和更高版本”的插件 API 上,被定义和“实现为标准”。后者只实现了整个 COM 接口的一个子集。
10.对于某些应用程序,COM 至少在某种程度上已被 Microsoft .NET 框架取代,并通过 WCF 支持 Web 服务。但是,COM 对象可以通过 .NET COM Interop 与所有 .NET 语言一起使用。联网 DCOM 使用二进制专有格式,而 WCF 鼓励使用基于 XML 的 SOAP 消息传递。
11.COM 与其他组件软件接口技术(例如 CORBA 和 Enterprise JavaBeans)非常相似,尽管它们都有自己的优点和缺点。
12.与 C++ 不同,COM 提供了一个稳定的应用程序二进制接口 (ABI),在编译器版本之间不会改变。这使得 COM 接口对“使用不同编译器版本编译的客户端使用的面向对象的 C++ 库”具有吸引力。

二、技术细节

1.概述

  COM 程序员使用 COM 感知组件构建他们的软件。 不同的组件类型由类 ID (CLSID) 标识,它们是全局唯一标识符 (GUID)。 每个 COM 组件都通过一个或多个接口公开其功能。 组件支持的不同接口使用接口 ID (IID) 来区分,接口 ID 也是 GUID。 COM 接口具有多种语言的绑定,例如 C、C++、Visual Basic、Delphi、Python 和一些在 Windows 平台上实现的脚本语言。 所有对组件的访问都是通过接口的方法完成的。 这允许进程间进行编程的技术,甚至是计算机间进行编程的技术(使用 DCOM 的支持)。

2.接口

  所有 COM 组件都实现了 IUnknown(自定义)接口,该接口公开了用于引用计数和类型转换(强制转换)的方法。 自定义 IUnknown 接口由一个指针组成,该指针指向一个虚拟方法表。该表又包含一组指针,这组指针分别指向不同的函数,这些函数是对接口中声明的函数的实现;这组指针顺序与在接口中声明的顺序相同。 因此,进程内调用开销与 C++ 中的虚拟方法调用相当。

   除了自定义接口,COM 还支持调度接口(从 IDispatch 继承)。 调度接口支持 OLE 自动化的后期绑定late binding)。相比比自定义接口,有更广泛的编程语言本地访问(natively access)调度接口

3.类(coclass)

  COM 类(“coclass”)是一个或多个接口的具体实现,非常类似于面向对象编程语言中的类。 类是基于它们的类 ID (CLSID) 或基于它们的编程标识符字符串 (ProgID) 而创建的。 像许多面向对象的语言一样,COM 提供了接口与实现的分离。 这种分离在 COM 中尤为明显,在 COM 中不能直接访问对象,而只能通过它们的接口访问。 COM 还支持同一接口的多个实现,以便客户端在运行时可以选择实例化接口的哪个实现。

4.接口定义语言和类型库

  类型库包含用于表示 COM 类型的元数据。这些类型使用 Microsoft 接口定义语言 (MSIDL/IDL) 进行描述。 IDL 文件以独立于语言的方式定义面向对象的类、接口、结构、枚举和其他用户定义的类型。 IDL 在外观上类似于 C++ 声明,带有一些额外的关键字,例如“interface”和“library”【用于定义接口和类集合】。 IDL 还支持在声明前使用方括号属性来提供附加信息,例如接口 GUID 以及指针参数和长度字段之间的关系。

   IDL 文件由 MIDL 编译器编译。对于 C/C++,MIDL 编译器生成一个独立于编译器的头文件(其中包含与声明接口的 vtbls 匹配的结构体定义),以及一个包含接口 GUID 声明的 C 文件。代理模块的 C++ 源代码也可以由 MIDL 编译器生成。此代理包含一些方法存根(method stubs),这些方法存根用于将“ COM 调用”转换为“远程过程调用(RPC)”,以启用 DCOM 进行进程外通信。

   IDL 文件也可以由 MIDL 编译器编译成类型库 (TLB)。 TLB 文件包含二进制元数据,这些元数据可被不同语言的“编译器和运行时环境”处理(例如 VB、Delphi、.NET 等),以生成特定于语言的构造(构造函数?),来表示 TLB 中定义的 COM 类型。  

5.作为对象框架

  因为 COM 是一个运行时框架,所以类型必须在运行时可以单独识别和指定。 为此,使用了全局唯一标识符 (GUID)。 每个 COM 类型都指定了自己的 GUID,以便在运行时进行识别。 为了在编译时和运行时都可以访问有关 COM 类型的信息,COM 使用类型库。 正是通过有效使用类型库,COM 才实现了其作为动态框架的能力。

  包含 COM 接口和类的 IDL 文件被编译成类型库 (TLB) 文件后,客户端可以在运行时解析这些 (TLB) 文件以确定对象支持哪些接口,并调用对象的接口方法。

 

本文译自:https://en.wikipedia.org/wiki/Component_Object_Model

 

组件对象模型

上一篇:6.页面绘制-帖子列表页和前端路由


下一篇:实现ios常见菜单效果的思路