COM,Component Object Model 简介
1. COM 是什么
COM 的英文全称是,Component Object Model,中文译为,组件对象模型。它官方的概念是:
The Microsoft Component Object Model (COM) is a platform-independent, distributed, object-oriented system for creating binary software components that can interact.
与其说 COM 是 System,更确切的说,应该叫做 Standard。因为它实际上是一套公共的 binary 标准,用于规定 software component 的接口的标准。也有人会把 COM 叫做 Common Object Model,但这其实是一种误传,起源于当初一名微软的工作人员 Mark Ryland!
但是,在长期的使用中,大家口中念叨的 COM 渐渐生出了各种各样的含义,已经不仅仅是最初的含义了。这也是为什么,对于初学者来说,理解起来特别费劲。因为总会查到层出不穷,又参差不齐的含义,让人很疑惑到底哪个含义才是标准!
- 首先,在系统设计上,它是一种设计理念
- 然后,在 Object 的世界中,它是那个世界中的规范和标准
- 再然后,在编程语境下,它是一种可以调用的其他程序的接口
- 再然后,在实际的电脑文件中,它多数是一个个DLL 文件
- 最后,在内部性质上,它是一个个二进制Binary的小程序
其实在我 Research 的时候,这些概念也是最头疼的地方。因为对 COM 概念的不了解,所以无法区分在不同视角,或者不同角度下的概念。而在 Research 的时候,往往会看到很多不同的网页,给出各种 COM 的概念。而让人头疼的就是,这些概念都不统一,让人无法理解。甚至开始怀疑,这些网页真的都是说的同一个东西的概念么?这种混乱,就是因为,不同的网站,在解释 COM 的时候,用的是不同的角度。而同一个东西,在不同的角度和情景之下,自然会有不同的含义。所以,往往 COM 到底是什么,要因情景而视之!但是,上面列出的几个角度,已足以让我们对 COM 的概念,构建出一个较为立体的理解了!
COM就是一个可以用于构造组件的模型。组件就是一个程序包(Package)或者一段功能模块(module),或者说是一个可执行程序(EXE)或DLL。作为一种模型,COM组件对象模型规范(The Component Object Model Specification)的正式文献中完整地给出了定义。该文献制订了一个二进制标准,允许异构型组件无缝地相互协同工作。COM就是这样的一个二进制标准,允许异构型组件无缝地相互协同工作。COM就是这样的一个二进制标准,因为它允许一个组件在无需另一组件源代码的情况下,重用该组件。除了作为二进制标准,COM还指定了一系列规范和要求,用以构件软件组件。然而,它仅仅是一种规范,并不强制使用某种特定的语言、工具或操作系统来创建组件的软件。
2. 科技历史与 COM 的由来
要了解 COM 的历史由来,我们首先要从科技发展的历史开始捋顺下来。先说 Object Oriented 这种概念,其实,这种概念据说是19世纪60年代就有了,是源自于 MIT。但是那个时候 PC 还没有普及,大多数公司使用的都是十分昂贵的大型机,微软还没有成立,这种情况下,自然对软件的需求也是非常基本的,大多数停留在数学计算,文字处理,和军事使用的范围。而且那个时候,CPU 的概念都还没出现,自然电脑也是不可能具备足够的运算能力的。第一个 CPU,是 Intel 在 1971 年,为完成一家日本公司的订单而设计发明的,自此才解锁的计算的巨大潜力,进入了现代计算机的篇章。而 CPU 的发展与成熟,才造就了后来的软件行业。微软也于 1975 年正式成立。同年,IBM 也开始生产 Portable Computers。那时起,微型电脑开始变成潮流。Microsoft BASIC 这种最早期的编程语言,也诞生于 1975年。那时候,绝大多数的微型电脑,虽然系统都不同,但是几乎都支持 BASIC 这种编程语言。正是这种编程语言,成为了日后微软的基础。1981年,微软首次为 IBM 提供了操作系统,叫做 QDOC,是微软的第一套系统,但却是买来的,别人研发的系统。1983年,微软研发出了 Lotus Software,是最早期的电子表格软件,这个软件成为了 IBM 电脑上的明星软件,装机必备。后来 1985年 Windows 1 诞生了,同时伴随着 Microsoft Excel 的诞生。自此之后,软件行业开始变得日益繁荣,微软也开启了自己的软件帝国。
软件行业变得日益繁荣,但是 Object Oriented 这种思想,还并没有发展到一定的高度。那时候,开发个软件或者系统是非常麻烦,非常复杂的。日后,想给软件添加一个功能,或者升级一个功能时,就更麻烦,因为,没办法独立的,去更新,或者改进,某一个特定的功能。若想要添加新功能,需要全盘改动后,再重新进行编译,非常的费时费力。于是人们就开始想办法解决,上面这个问题,然后 Object Oriented Programming(面向对象的编程)的概念就开始兴起。这时,虽然面向对象编程的概念已经兴起,但是,还没有统一的 Framework 或者说是标准,能让不同软件之间里的 Object 可以互相交流。于是,不同的软件,就变成了一个个,孤立在大海中的小岛,里面住着一堆 Objects,无法和外界交流。人们想出的解决办法就是,开发一个系统或者体系,在这个体系中,写软件的人只需要制造出,Software Component 就行了。而,这个 Component 就像是,买回来一个,方块形的,电子配件一样,插在我们自己的电路板上,就可以开始发挥作用。而这些,Software Component 外表上,必须遵循系统中的统一标准,而内部,就随便怎么编程都可以。后来,微软在1993年,开发出了这个标准,这标准就被叫做,Component Object Model (COM)。
我们再把 COM 形成前后的,技术发展,掰开来看下。首先,在 1987年,也就是在 Windows 2 发行的时候,Dynamic Data Exchange (DDE) 技术产生了,作为一种进程间通信手段(Inter-process communication)。在这个技术之前,只支持系统和客户端应用程序之间的通信,这个通信,则是通过 Windows Messaging Layer 实现的。而 DDE 技术,则再此基础之上,实现了客户端应用程序之间的通信,这也就成为了进程间通信技术的开端。但这时的通信,还只是停留在 Text conversations 和 Windows messages 的层面上。之后 Antony Williams 分别于 1988年 和 1990年 发表了两篇微软内部文章,分别是 【Object Architecture: Dealing With the Unknown】和【On Inheritance: What It Means and How To Use It】。正是两篇文章奠定了日后 COM 产生的理论基础。之后,1991年,微软在 DDE 的基础上,开发出了第一个 object-based framework(基于对象的框架),叫做 Object Linking and Embedding (OLE),即对象的连接与嵌入。
这个技术是同 Word 软件的发行一同发布的,专注于实现 Compound document(复合型文件),就是将 Excel 文件,嵌入到 Word 中。同在 1991年,微软发布了 Visual Basic 1.0 编程语言,并以 dynamic-link library (DLL) 的形式,附带了 Visual Basic Extensions (VBX) 插件。这个插件让使用者,可以通过 Properties and Methods 来操控 objects (对象)。1992年,随着 Windows 3.1 的发布,OLE2 和它自己的 Object Model,也一同发布了。和 OLE1 不同,OLE2 是在 COM 概念的基础上重新实施的。这时的 COM Application binary interface (ABI),即 COM 应用接口的标准也发生了改变。1994的时候,微软宣布,OLE2 改名为 OLE,从此 OLE 变成了微软组件技术(Component Technologies)的统称。同年还发布了 OLE Custom Controls (OCXs) ,作为 VBX 的升级版。后来,在1995年,微软发布了 Visual Basic 4.0,开始支持 OCXs,这时微软也开始考如何让 COM 组件可以实现跨语言支持。这就要求,COM 架构下,必须要提供一个一致的接口,以及提供一组可以调用接口内方法的能力。此后,才发展成了我们现今熟悉的 COM 的含义。在1996年,微软有发现 OCXs 可以应用在浏览器上,所以就把部分 OLE 改名为 Internet “ActiveX”,然后,逐渐的,所有的 OLE 都改名叫做 ActiveX 了。同年后期,微软又拓展了 COM 的能力,使得组件对象,拥有了在网络上通信的的能力。这个技术被称为 DCOM (Distributed COM)。自此便形成了今时今日的 COM 的概念。
3. 接口(Interface)周围的概念
个人认为,关于 COM,的一切的一切,最后都是为了这个“接口”。因为只有有了“接口”,才算是真正的实现了 Component Object 的理念(或者说,才算是实现了,把 Object 变成 Component 的想法)。因为只有有了“接口”,Component 才能被叫做组件,才能被调用。所以下面简单描述下,几个常见的,围绕着“接口”的概念。
3.1 API (Application Programming Interface)
API 中文为,应用程序编程接口;很多时候,都被直接叫做 接口
(Interface)。接口
是 操作系统
或 程序库
,提供给应用程序的,接入点,让应用程序能调用,系统某一方面的功能。其主要作用是,让开发人员,可以轻松调用这些功能,而不需要了解,到底怎么做到的,和底层代码。但是,API 并不是代码,他只是一个接口,或者说只是一个地址。
3.2 IDL(Interface Defining Language)
IDL 中文为,接口描述语言。它是一种 Specification language(规范语言)。是用来描述,软件 Component 的 API 的 “规范语言”。与之相比,Programming Language(编程语言)是可以直接运行,用于系统实现的,形式语言。而,“规范语言” 是通常不能直接运行的,而是用于系统分析和设计的,描述语言。然后,这些一段一段的用来描述 Interface 的文字,就被储存在了 IDL 文件中(文件后缀就是 .idl
)。每个这样的文件里面都有,一个 header 和一个 body。格式很整齐。
3.3 OLE (Object Linking and Embedding)
OLE 中文为,对象链接与嵌入。是能让应用程序创建,包含不同来源的文档,的复合文档技术。OLE 是建立在 COM 理念的基础之上的。COM 是理论框架,而 OLE 是根据这个框架,实施出来的一套技术。正如之前在,PC Mag 杂质上看到的一个副标题,就很好的诠释了这种关系型:
COM-the master plan that lets Windows apps interact through OLE.
一个比较常见的例子就是,把 Excel 表格,整个插入到 Word 文档中。而这个 Excel Object,就是通过这个 OLE 技术,连接并嵌入(Linking and Embedding)到 Word 中的。但,正如上文所说,后来 OLE 就变成了,微软组件技术(Component Technologies)的统称。而,像这样的一个典型的 OLE 功能(或 OLE 特性),其背后是有一大堆,Interface(接口)作为支持,才得以实现的。
3.4 GUID (Globally Unique Identifier)
GUID 中文为,全局唯一标识符,也被称为,UUID (Universally Unique Identifier),即,通用唯一识别码。是一个用于标识信息的,128-bit的,标识符;由一组,32位數的,16进制的,数字组成。数字串,的格式为 8-4-4-4-12 的32个字元;大概长成这样:550e8400-e29b-41d4-a716-446655440000
。GUID 具有全球唯一性,出现重复的概率几乎为零。所以才叫做,全局唯一标识符。
3.5 CLSID (Class IDentifier)
CLSID 中文为,类标识符。是一个 GUID,但是,是专门用于,标识 COM class object 的。每一个 OLE Class,都会有一个与之对应的,全球独一的 CLSID。
3.6 ProgID (PROGrammatic IDentifier)
ProgID 可以翻译为,程序标识符,或者,编程标识符。通常情况下,每个 CLSID,都会有对应的 ProgID。例如,ProgID 是 Msxml2.DOMDocument 的字符串;而 CLSID 则长成这个样子 {F9043C85-F6F2-101A-A3C9-08002B2F49FB}
。所以 ProgID 的存在,是为了编程的时候,方便调用。
3.7 Registry (Windows)
Registry 中文为,注册表。它是一个 hierarchical database (分层的数据库)。用于储存 Windows 系统,或者应用程序的 low-level settings。但并不是,所有的应用程序都选择把设置,存在注册表里。Registry 是从 Windows 3.0,推出 OLE 的时候,开始有的。在那之前,应用程序都是把自己的设置信息存在一个后缀为 .ini
的文本文件中的。除了设置之外,所有的 OLE Objects 的 CLSID, 也都储存在这个 Registry 中。感兴趣的同学可以去 Regedit.exe 中,这个位置 HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
看下,所有的 CLSID 都长成什么样。而在每个 CLSID 的“文件夹”中,又都会储存着,这个 Class 的 ProgID 的名字。
4. 调用组件的流程
阅读到这里的同学,应该已经对基本的概念有一些了解。那么我们就再来看下,在实际运行中,Component(组件)到底是怎么被调用的。就用在 Word 里面插入一张 Bitmap Image 来举例;当我们在 Word 程序里,点击插入 Object 的时候,Word 会弹出,插入对象的对话框。然后,程序会立刻开始扫描,系统的 Registry,看哪些 Object 是能够插入的,然后,把它们都列在你面前,供你选择。当你选中 Bitmap Image 这个对象后,程序会,立刻调出他的 ProgID 名字,然后,把这个名字,递给一个叫做 CoCreateInstance 的 OLE Function。再然后,在这个 Function 的内部,就开始了一系列流程。
首先 OLE 会用立刻这个 ProgID(或者 CLSID)去找出与它对应的 Regstry 条目。然后,通过注册表里登记的信息,便可以轻易的找到,提供这个“服务”的,应用程序,或者 Component(.exe 或者 .dll)到底住在哪里。一旦找到了,便可以立刻调用(Invoke)这个 Component,然后创建出,一个 Bitmap 对象的 Instance(这个Instance,似乎也叫做 Interface Pointer)。
这和我们写代码的时候是一样的,在我们要使用某个模块的功能之前,都是先通过 PorgID 创建一个 Instance(例如,在 VBScript 中,通常是用Set XL = CreateObject("Excel.Application")
这样的语句)。然后通过这个 Instance,和它提供的 Interface(接口),我们就可以开始调用,这个实例的各种属性和功能了(例如 XL.Workbooks.Open("FilePath")
)。
5. DCOM:分布组件对象模型
5.1 概述
在 Microsoft 推出 Windows NT4.0 之后,以往只有在大型主机或者工作站上才可能出现的分布式处理终于可以在PC的世界中工作了。造成 Windows NT 可以成为企业计算环境。除了NT的日渐成熟和执行效率增加以外,最重要的就是加入了DCOM(Distributed Component Object Model)的功能。Microsoft 在NT4.0 中第一次推出了该项技术,但是接着推出了DCOM For Windows95,在其推出的 Windows 98 中更内置了DCOM。它代表着使用 PC 环境也可以处理非常庞大和复杂的计算工作。通过该技术,PC级的程序员终于可以进入分布式对象的世界了。
Microsoft 的 COM 模型能够让同一台计算机中的各种对象相互沟通和使用对方提供的服务,而 DCOM 则更进一步地让不同的应用程序和对象可以在网络中不同的计算机之间沟通。这意味相可以在应用程序中或者动态链接程序库中建立对象,并且提供这个对象的各种服务,然后在另外一台不同的机器中的应用程序可以调用这个对象的方法或者是访问它的属性值。 DCOM 为什么如此重要呢?图为目前软件发展的趋势是走向以组件为基础的分布式计算 , 而在不同的织件中需要一个相互沟通的通信协议。这就像 PC 中的各种适配器 , 它们是援在 PCI 和 ISA 等总线之上 , 通过总线和其他计算机组件迹行沟通。组件也需要一个相互沟通的总线 , 使用一致的通信协议来沟通,而 DCOM 就是这种组件的总线。它负责各种组件之间的信息传递。如果没有 DCOM,那么就达不到分布计算环境的要求。
DCOM 是构造于 COM 之上的。在 COM 中,程序通过指定一个对象的ID(Class GUID)和要访问的接口 ID,就能够访问这个对象的特定接口中的方法和属性。
COM 模型中访问对象接口中的方法或属性如上图所示,在 COM 的基札模型中,不同的应用程序和对象之间可以通过指定对象和接口 ID 来取得对方的服务 , 但这种模型是发生在同一台计算机中。如果在 A 计算机中的应用程序或者对象希望访问在计算机 B 中的特定对象的服务 , 应该怎么办昵?在基本的 COM 模型中无法做到这一点,Microsoft 用 DCOM 解决了这个问题。如下图所示 :
从上图可以看出,在使用 DCOM 时和使用 COM 建立对象的方式是相同的,只需再加入一个机器名称的参数。如果在 COM 中是使用 Windows API 的CoGetClassObject 建立对象的话,那么只需要再输入机器名称的参数即可在远程指定的计算机中建立对象,并且取得指定接口的信息 . 简单的说 , DCOM 是 COM 的延伸,它让对象和接口的建立可以跨越不同的机器,并且保持和 COM 的兼容性。它构造于 RPC(Remote Procedure Call)的技术之上 , 并且使用 TCP/IP 作为网络通信协议。 NT4.0 和 Win98 部直接支持 DCOM,Win95 中可以安装 DCOM For Windows95 来支持它。Microsoft 对 DCOM 也在进行不断的完善,例如在 NT4.0 的 Server Pack 1、Server Pack 2、Server Pack 3 以及 Server Pack 4 中 , 对 DCOM 的支持越来越好 , 其中在 Server Pack 2 中有一个 DCOM 非常重要的功能是开发 N-Tier(多层)应用程序必须使用的。现在 DCOM 已经占据了非常重要的地位,Microsoft 的 SQL Server、Transaction Server. Message Queuing Seryer 等部充分利用 DCOM 来进行企业中的分布式计算。
5.2 COM/DCOM 包含的技术
COM 规范包含了几种成功的技术包括:动态链接、口向对象的模型和客户/服务器模型。
5.2.1 面向对象的模型
面向对象的编程之所以成功 , 正因为它支持封装、继承性和多态性。我们将简要地回顾一下这些传统概念。这桦 , 我们就可以大致了解 COM 是如何吸收斧改进它们的。
5.2.2 封装性
封装性(encapsulation)或者隐藏变量和可能存在的函数,使调用程序只看到它所需要看到的信息,这是面向对象编程的重要原则。对议用程序隐藏了信息,对象就可以控制其内部变量并防止意外错误和非法的外部访问发生。这一点十分重要,因为它在容许调用程序可靠地使用对象的同时,也使对象改变或增强其内部功能所需的维护最小化了。除了支持对状态(state)和行为(behavior)的列集外,封装允许我们把接口和实现分离开来。总体来说,对象所发布的行为集合就称为“接口“。外部世界与一个对象都是通过它发布的接口来相互作用的。将接口与实现分开意味着,这个世界无需理会那些隐藏在发布了的行为之后那些烦人的实现方法。这些行为在对象周园有效地构筑了一道栅栏,封装和保护了对象内部的实现和数据。既然客户只能看到发布了的行为 , 水远看不到内部的实现和数据,这样就减少了对象与其客户之间的糊合(coupling)。COM 不仅支持和吸收了封装性 , 而且大力加强了这一概念。COM 要求区分接口与实现。在 COM 中 , 外部世界只知道一个对象支持的接口,而永远无法看见这个对象的内部实现。凭借封装的严格性,COM 赢得了它今天所拥有的卓然地位。这是因为,正确使用封装,能够获得“黑盒“(black box)式的组件集成。此概念允诈在不破坏原完整系统的前提下 , 计组件在以后的一定时间里升级发展。
5.2.2.1 继承性
继承性(inheritance)可用于扩展或继承类的状态和行为。最初定义的类称为“基类“(base class), 由它扩展所创建出来的新类秘为“派生类“(derived class)。简单继承提供接口和实现的重用性。这一概念强有力的地方在于:你不必通过不断地复制和粘贴代码来实现时可怜的代码重用。通过继承堆类 , 就可以得到基类建立的所有状态和行为。更有吸引力的是实现继承性 , 即重复使用先前写好的代码。
通常情况下,重用可以在源代码级上完成,但是对于组件世界,重用可以在二进制级上完成。二进制级的代码重用允许那些不同的软件发行商不再受限于某种编程语言或工具,允许开发的异构组件间有更多的协同合作。
5.2.2.2 多态性
多态性的意思是使用同一个名称去引用一系列不同的方法(函数)。这一概念允许在运行时,基于某一个对象选择最合适的那一种方法来实现。换句话说,它支持迟绑定(Iate binding),即在运行时根据对象的真实类型动态地、有选择地去调用某个方法。
客户/服务器模型
客户 / 服务器模型有许多优点,但没有哪个优点能像系统的稳定性那样激动人心。在客户/服务器的世界里,一台服务器可以同时支持很多客户。如果其中一部客户瘫痨的话 , 它不会拖垮服务器和其他的客户、同理,如果服务器崩溃了,只要那些客户处理断开连接 , 也不会受到影响。稳定性正是 COM 要包含客户/服务器模型的主要原因。为了讨论方便 , 我们假设“客户“(client)就是使用其余实体(任意一段代码)的服务的某一个实体,而“服务器“ (server) 就是服务于客户要求的一个实体。如果你接受这个简单的假设 , 就可以很容易地推出一系列客户/服务器的类比:
- 一个进程(客户)通过简单的函数调用与一个DLL(服务器)进行通信。
- 一个进程(客户)通过系统调用与操作系统(服务器)通信。
- 一个进程(客户)使用命名管道与同一机器上的另一个进程(服务器)通信。
- 一个进程(客户)通过套接字(socket)与另一远程机器上的另一进程(服务器)通信
在上面的这些方案中,你己经见识了客户/服务器的概念。但是,这里还有个问题:在每个方案中客户和服务器之间的通信都是不同的。具体说来,你看见了四种不同的客户与服务器协同合作的方式。为了消除这些差异,COM 指定了一条所有组件都必须遵守的通信标准。这条通信标准就是 COM 接口 ,也可以看作一个容户与一个服务器协同合作的通用途径
。有了 COM 接口 , 大家就可以在单一的通信方式一一也就是说,一种通用语言上达成一致。COM 从 RPC 处继承了这一标准,支持客户/服务器通过一个 RPC 接口通信。
6. COM/DCOM 的功能和服务
一个分布对象的体系结构要支持许多公认为必须的特征:位置透明性、动态和远程对象的激活、安全性、接口、生存期支持和动态发现、二进制互操作性、连接管理、并发管理、重用、接口储藏库、实现储藏库、静态调用、动态调用和事件。
6.1 位置透明性
当一位客户用 COM 调用一个方法时,它认为此方法是在本地执行的。但事实上,此方法可以存在于网络空间中的任何地方。它可以和客户位于合一进程中,位于同一台机器的不同进程中,或者位于第三方机器的一个进程中,这就是位置透明性的含义。
位置透明性主要依赖列集。位置透明性的优势在于 , 针对某一目标编写代码时,不必考虑目标的物理位置,这样,赋予程序更大的自由度和可移植性,还可以允许更好的伸缩性和容错性。
6.2 动态和远程对象的激活
COM SCM 支持远程激活,可以在任何支持 COM 的机器上安装。它的目的是应客户的请求,动态地定位和激活分布式对象。如果对象存在于同一台机器的 DLL 中,COM 会为使用此对象的客户进程动态地加载 DLL。如果对象他在于同一台机器的独立可执行文件中,COM 会要求其本地的 SCM 激活该可执行文件,这样客户进程就可以使用此对象了。如果对象存在于一台远程机器中,就需要一定的协调了。在这种情况下,客户机上的本地 SCM 会与还程 SCM 联系,而远程 SCM 会负责激活远程 EXE 或 DLL。对远程 EXE,远程 SCM 仪仅产生它罢了,但对远程 EXE,远程 SCM 要激活一个己注册的代理进程来动态加载此 DLL。
6.3 安全性
COM 支持启动、访问和调用级的安全性。启动安全性,或者叫做激活安全性,决定谁可以启动或激活服务器组件,从而保护了服务器。COM 也支持扮演。这一特性允许服务器在激活或执行客户进程的那个用户的安全环境下运行 , 换句话说,服务器可以完成系统中其他部分允诈该客户所做的事情。在扮演客户后,对象做的所有访问,都受到该客户的用户安全环境的限制。在扮演客户完成其任务后 , 对象就会返回到自己的安全环境中。
6.4 接口
在时间和空间上 , 每个接口都是独一无二的 , 因为它被分配了一个 IID,那是一个 128 位的 GUID。这同时也意味着版本的支持实际上是自动的,因为每个接口都包含了在全局唯一的标识符。
6.5 生存期支持和动态发现
对象最重要的特征之一就是其生命周期,因为对象必须被正确地创造和销毁。在 COM 中,使用引用计数来支持对象的生存期管理。通常,一个对象会保留所有客户的计数。每当一个客户要求使用一个对象的接口时,该对象的引用计数就会增长:而当一个客户释放了接口,引用计数就会减少。一旦此引用计数达到零 , 该对象就会自动清除并销毁掉自己。
6.6 二进制互操作性
二进制互操作性是软件重用的一个重要方面。当部署一个开发函数库时,必须装载头文件和库文件。如果以前的客户必须把库链接进他们的系统,才能让他们的系统工作,那么组件技术诞生后,只需装载二进制代码就可以工作了,不需要头文件,也不霁要链接到库文件。二进制互操作性不仅让软件集成更容易,它还允许了插件组件的开发和集成。
6.7 连接管理
简单的连接管理依赖对象的生存期管理。对象一直与客户保持虚拟的连接,如果引用记数大于 0,对象就假想客户一直活动。但是,如果客户由于某种原团没有释放引用的对象,那么对象将永不释放其占有的资源。COM 通过一种简单的偏执检查(paranoia check)来支持连接管理。每个 COM 机器都运行了一个名为 OXID 分鲜器(resolver)的特殊协调器/管理器 (coordinator/manager)、服务器端的 OXID 分解器监听来自客户 OXID 分解器的 ping。客户端的 OXID 分解器聚集针对某一特定机器的所有 ping,这种根集称为一个 ping 集,由一个动态产生的 ping SETID (集标识符)来表示。有了聚集,客户端的 OXID 分解器可以只给服务器的 OXID 分解器发送一条 ping 信息 , 但是代表个很多客户到服务器的 ping,从而减轻了网络负担。为了进一步提高性能 ,COM 定期在集合中传送变更(增量),如果服务器的 OXID 分解器连续三个周期没有收到某一个对象的 ping,COM 就认为客户已经不存在,并执行垃圾回收工作。
6.8 并发管理
COM 将不同并发语义(concurrency semantics)的对象分离开来,归入独立的执行环境,称为套闭(apartment)。对象在它自己的套间里生成、存在和死亡 ,
如果要在另一个套间中使用这个对象,必须对它列集。列集意味着引入套闭要处理一个对象的代理,而不是原始对象,此代理对象在引入的套间中存在,并和它的客户代码共享相同的并发语义。COM 提供了许多的不同的线程和并发模型来支持异构组件的软件开发。
6.9 重用
COM 支持包容(containment)和聚集 (aggregation)。包容可用于将被重用的对象隐藏在正在开发的对象之后,然后,发布一系列通道(passthrough)或代理方法来让客户使用这些隐藏对象的服务。当客户调用通道方法时,需要将这些调用委派到正在重用的包容对象里。聚集可以把重用对象的接口直接暴露给客户。为了聚集,对象必须将他的 Iunknown 指针传递给被重用的对象 , 以便生存期管理可以正常工作。
6.10 接口储藏库
为了使重用和集成更简单 , 一个分布式对象的环境必须提供一种让客户发现对象及其支持的接口的方式。在 COM 中 , 一个对象的类型信息在接口的储藏库中详细的存储,称为类型库(type library)。类型库存储与其对象及其所支持的服务有关的全部信息。通常 , 一个类型库是一个独立的二进制文件 , 以 .tlb
作文件的扩展名。
6.11 实现储藏库
如果已经得到了一个组件的信息,仍然需要找出该组件的位置。在分布式环境中,一个实现储藏库存储了对象实现的位置。COM 通过注册表来支持这一概念。COM SCM 使用记录在注册表的某一特定的实现的位置来动态地激活对象。
在客户端,SCM 查找注册表来决定远程组件在什么位置。然后 , 和服务器计算机上的远程 SCM 联系,该远程 SCM 查找它自己的本地注册表来获得组件的位置信息 , 从而激活组件。
在 Windows 2000 中,利用活动目录(active directory)为实现储藏库提供了更好的支持。
6.11.1 静态调用和动态调用
静态调用就是指简单的函数调用,要求在编译的时候就知道方法及其签名,这样编译器就可以在调用的方法的方式上施加限制。在 COM 中静态调用有:
-
vtbl 绑定:通过 vtbl 调用接口方法。这种调用间接地指向了实际方法,可以跟随指向 vptr 的接口指针找到 vtbl,而 vtbl 包含了指向实际方法的指针,这种技术又叫极早绑定(very early binding)
-
ID 绑定:通过使用类垣库和一个名为 Idispatch 的特殊接口。此类型库中包含了一个名为 dispid 的数字,它可以代替接口中的一个实际方法 , 这种方法又叫早绑定(early binding)。
-
双接口:COM 同时允许 Idispatch 和 vtbl 调用
三种技术。
动态调用被称为是自动化(Automation),并由 Idispatch 支持。使用这种方法,首先给出一个方法或属性的名称代唯与之关联的 dispid,查找之后就可以使用 dispid 来调用。
6.11.2 事件
事件是分布式环境一个十分重要的特征:当某一特定事件发生时,对象有能力通知对方。这种事件通知可以帮助其他对象决定他们需要采取什么行动。 COM 通过一个叫做连接点的的慨念来支持事件,这就需财有两个合作者:源点 (source)和汇点(sink)。对捕获某一事件感兴趣的客户(汇点)必须将自己的意向告诉它们的对象 ( 源点 )。
附录
这篇文章中涉及到了不少的历史,把近200年的科技发展历史 Technology Timeline 写在博客里。把微软技术发展的 Timeline,和科技发展的 Timeline 揉合在了一起,这样能帮助我们感觉到,技术是在伴随着科技的发展而发展。也可以看到,COM 这种技术理念的产生,是在PC渐渐普及起来,操作系统渐渐成熟,软件需求逐渐提高之后才有的。所以很多事情的发展,往往都是自然而然的,因为有了需求,才会有相应的发展。COM 的产生,从这个角度说,也是一种必然。因为 COM 实际上,就是一种规范,就像行业规范一样,行业太小自然不用规范,而规模大了,需求大了,自然会产生规范,所以 COM 的产生是一种必然结果。而技术的发展,既在推进着科技的发展,也受制于现有科技的边缘。
Year | Technology | Inventor | Type |
---|---|---|---|
1823 | Silicon (Si) | Baron Jons Jackob Berzelius | CPU |
1833 | Analytical Engine | Charles Babbage | Computer |
1872 | Analog Computers | William Thomson | Computer |
1903 | Electrical Logic Circuits (Gates) | Nikola Tesla | CPU |
1904 | Diodes Vacuum Tube | John Ambrose Fleming | CPU |
1928 | Punched Cards | IBM | Storage |
1928 | Magnetic Tape | Fritz Pfleumer | Storage |
1932 | Drum memory | Gustav Tauschek | Storage |
1936 | Turing Machine (Mechanical Computation) | Alan Turing | Computer |
1938 | Electromechanical Analog Computer | United States Navy | Computer |
1939 | Vacuum Tube Data Processing System | Tommy Flowers | Computer |
1942 | Atanasoff–Berry Computer (ABC) | John Vincent Atanasoff; Clifford E. Berry | Computer |
1943 | Colossus Computer (First Crude Computer) | Tommy Flowers; British Codebreakers | Computer |
1946 | ENIAC Computer | Mao Qili; Ai Kete | Computer |
1946 | Delay Line Memory System | J. Presper Ecker | Storage |
1947 | Williams Tube | Freddie Williams; Tom Kilburn | Storage |
1947 | Transistor | John Bardeen; Walter Brattain | CPU |
1947 | Magnetic-Core Memory | An Wang; Way-Dong Woo | Storage |
1948 | Manchester Baby (Stored-Program Computer) | Frederic C. Williams; Tom Kilburn; Geoff Tootill | Computer |
1953 | Video Tape Recorder | Norikazu Sawazaki | Tech |
1954 | Solar Battery | Calvin Souther Fuller; Daryl Chapin; Gerald Pearson | Tech |
1956 | Hard Disk Drive (HDD) | IBM | Storage |
1957 | First Personal Computer (PC) | IBM | Computer |
1958 | Integrated Circuit (ICs) | Jack Kilby; Robert Noyce | CPU |
1959 | MOSFET (MOS Transistor) | Mohamed Atalla; Dawon Kahng | CPU |
1960 | Transistors Mass-Production Facility | IBM | CPU |
1962 | Atlas Computer (Supercomputers) | Ferranti International plc | Computer |
1963 | Integrated Bipolar Static Random-Access Memory (SRAM) | Robert H. Norman | Storage |
1964 | MOS Semiconductor Memory | John Schmidt | Storage |
1965 | Dynamic Random-Access Memory (DRAM) | Toshiba | Storage |
1960s | Object-Oriented Programming | MIT | Tech |
1965 | Moore’s Law | Gordon Moore | CPU |
1968 | Silicon-Gate MOS Integrated Circuit (MOS IC) | Federico Faggin | Storage |
1968 | Intel Corporation (Founded) | Gordon Moore | CPU |
1969 | ADM (Advanced Micro Devices) (Founded) | Jerry Sanders | CPU |
1969 | ARPANET | UCLA; SRI; UCSB; The University of Utah | Tech |
1970 | Pocket Calculator | Texas Instruments | Tech |
1970 | DRAM IC Chip | Intel | Storage |
1971 | Floppy Disk | IBM | Storage |
1971 | Ray Tomlinson | Tech | |
1971 | Single-Chip Microprocessor (Intel 4004) | Intel | CPU |
1972 | Microsoft Partnership | Microsoft | Microsoft |
1972 | Video Game Console | Ralph H. Baer (Team) | Tech |
1973 | First Commercial Graphical User Interface | Xerox Alto | Tech |
1973 | Capacitive Touchscreen | CERN | Tech |
1973 | Internet Protocol Suite (TCP/IP) | Vinton Cerf; Robert E. Kahn | Tech |
1975 | Microsoft Found | Microsoft | Microsoft |
1975 | IBM 5100 Portable Computer (Portable Computer) | IBM | Computer |
1975 | Microcomputer Revolution | Altair 8800 | Tech |
1975 | Microsoft BASIC | Microsoft | Microsoft |
1980 | Flash memory | Fujio Masuoka | Storage |
1981 | QDOC | Microsoft | Microsoft |
1982 | CD-ROM | Sony; Philips | Storage |
1983 | Lotus Software | Microsoft | Microsoft |
1983 | Multi-Tool Word | Microsoft | Microsoft |
1983 | Stereolithography | Chuck Hull | Tech |
1984 | Macintosh | Apple | Computer |
1984 | Cell Phone | Motorola | Tech |
1984 | lithium-ion battery | John B. Goodenough; Rachid Yazami; Akira Yoshino | Tech |
1985 | Microsoft Excel | Microsoft | Microsoft |
1985 | Windows 1.0 | Microsoft | Microsoft |
1987 | Windows 2.0 | Microsoft | Microsoft |
1987 | Dynamic Data Exchange (DDE) | Microsoft | Microsoft |
1988 | Antony William, Paper 1 (COM) | Microsoft | Microsoft |
1990 | Windows 3.0 | Microsoft | Microsoft |
1990 | Microsoft PowerPoint | Microsoft | Microsoft |
1990 | World Wide Web | Tim Berners-Lee | Tech |
1990 | Antony William, Paper 2 (COM) | Microsoft | Microsoft |
1991 | Visual Basic 1.0 | Microsoft | Microsoft |
1991 | Object Linking and Embedding (OLE) | Microsoft | Microsoft |
1991 | Dynamic-Link Library (DLL) | Microsoft | Microsoft |
1992 | Visual Basic 1.0 for DOS | Microsoft | Microsoft |
1992 | Visual Basic 2.0 | Microsoft | Microsoft |
1992 | Synchronous Dynamic Random-Access Memory (SDRAM) | Samsung Electronics | Storage |
1992 | OLE Version 3.1 | Microsoft | Microsoft |
1992 | Windows 3.1; OLE 2 | Microsoft | Microsoft |
1992 | COM Application binary interface (ABI) | Microsoft | Microsoft |
1993 | Visual Basic 3.0 | Microsoft | Microsoft |
1993 | VBA (Visual Basic for Applications) | Microsoft | Microsoft |
1993 | Web Browser | Mosaic | Tech |
1994 | PlayStation | Sony | Tech |
1994 | OLE custom controls (OCXs) | Microsoft | Microsoft |
1994 | OLE2 change to OLE | Microsoft | Microsoft |
1995 | Visual Basic 4.0 | Microsoft | Microsoft |
1995 | DVD | Philips; Sony; Toshiba; Panasonic | Storage |
1996 | OLE change to ActiveX | Microsoft | Microsoft |
1996 | VBA 4.0 | Microsoft | Microsoft |
1996 | DCOM | Microsoft | Microsoft |
1997 | Microsoft Partnership with Apple | Microsoft | Microsoft |
1997 | Visual Basic 5.0 | Microsoft | Microsoft |
1998 | Visual Basic 6.0 | Microsoft | Microsoft |
1998 | DDR SDRAM (Double Data Rate SDRAM) | Samsung Electronics | Storage |
1998 | GDDR (Graphics DDR) | Samsung Electronics | Storage |
1998 | MP3 player | SaeHan Information Systems | Tech |
1998 | Windows 98 | Microsoft | Microsoft |
2000 | Windows ME | Microsoft | Microsoft |
2001 | Windows XP | Microsoft | Microsoft |
2002 | .NET Framework | Microsoft | Microsoft |
2007 | Windows Vista | Microsoft | Microsoft |
2007 | iPhone | Apple | Tech |
2008 | Visual Basic 6.0 (support ended) | Microsoft | Microsoft |
2008 | Google Chrome | Tech | |
2009 | Windows 7 | Microsoft | Microsoft |
2010 | Ipad | Apple | Tech |
2011 | 3D transistors | Intel | Tech |
2012 | Raspberry Pi | Tech Volunteers | Tech |
2015 | Windows 10 | Microsoft | Microsoft |
2015 | AlphaGo (AI) | Tech | |
2019 | Quantum computing | IBM | Computer |