COM

来源:互联网 发布:淘宝上做网站的靠谱吗 编辑:程序博客网 时间:2024/04/28 16:51

COM(含DCOMCOM+)组件技术存在许多问题,其中有一些是关键的,有的甚至是致命的。

组件技术主要强调在独立开发和部署的程序之间的一套约定(contract),COM则是微软公司将这些约定规范化的首次尝试。COM既能作为设计范例(paradigm)(它将组件的约定,表示为类型定义),也可用作支持平台技术。作为前者,COM编程模型相当成功;但是后者却存在诸多问题,正是由于缺乏稳固的平台技术,COM时代面临着终结。

组件间的约定,纯粹是通过用户与组件之间的语义保证和假设的形式来表示的。但是,仍需要定义某种形式来表示语义,专业的做法是——采用可编程的类型定义,以及描述这些类型定义的人工可读文档。

COM用类型的形式表示组件约定,但是该约定存在如下两个关键问题,使得其对语义的表示并不是最优的。

1.约定的描述:

COM没有定义约定的交换格式,即COM规范所约定的类型定义,必须通过完全是COM之外的某种技术来进行交互。微软定义和支持的COM交换格式有两个——IDLInterface Definition Language接口语言定义)和TLBType LiBrary类型库),但是这两种格式并不是同构的,其中也没有哪种格式是权威的或标准的。

另外,COM的描述约定方式,至少还存在两个其他的关键问题:

COM缺乏对组件依赖性的描述。因此,没有办法来解析COM组件(或者其约定的定义),也不能确定它所需要的其他组件,从而无法保证它的正确运行。由于缺少相关信息,使得部署基于COM的应用程序,很难确定它需要哪些DLL,也不能静态确定所需要的是哪个版本的组件,这让对版本问题的诊断变得极其复杂;

COM约定的描述格式缺乏扩展性。IDL是基于文本的,极少随组件部署,通常只有C++程序员才会使用。但是,在MTS下开发企业应用的C++程序员很少,这使得IDL约定用处不大。TLB在扩展性方面存在缺陷,而且VBTLB/MTS之间被隔离开来,这最终导致了TLB的没落。

2.约定的工作方式:

COM组件的约定是基于类型描述的,所采用的类型系统是C++的可移植子集。而且COM对组件的约定是物理的(二进制约定)。它要求:每个方法都具有精确的虚函数表vtable偏移量、每个被传递的参数在堆栈规则中都有明确的偏移量、对象引用采用接口指针的明确格式、使用规定的分配器进行被调用这内存分配。

就底层技术而言,COM组件的约定,最终只是在内存中形成堆栈结构的协议,根本没有(按组件所要求的那样来)描述语义内容。二进制的物理约定,过度关心细节,使COM难于使用和开发。尤其在针对COM组件的版本控制问题上,物理性约定所产生的问题就更大了。这使得COM组件,难以进行语义修改和版本升级。

COM组件的约定定义的精确性,产生了高效的代码,但这却是以难以接受的不可靠性和开发使用及扩展升级的困难与复杂性为代价的。

2CLRCLI

为了解决COM所存在的这些问题,微软公司的COMMTS小组,计划开发一个新的组件平台。开始时叫COM3COM+ 2.0,后来又叫CORComponent Object Runtime,组件对象运行时)和URTUniversal Runtime通用运行时),最后才被命名为CLRCommon Language Runtime,公共语言运行时[/])。它是现在(由微软提交的)成为国际标准的CLICommon Language Infrastructure公共语言基础结构)在Windows平台上的一种具体实现。

CLI是针对可执行代码格式、以及能执行该代码的运行时环境的一种规范。CLI标准包含如下几个主要组成部分:

l CTSCommon Type System公共类型系统)——被编译器、工具和CLI本身所共用的一种统一类型系统。 它是一个模型,定义了在声明、使用和管理类型时,CLI应遵循的规则。CTS建立了一个框架,使跨语言集成、类型安全和高性能的代码执行成为可能;

l CLSCommon Language Specification公共语言规范)——语言设计者和框架(类库)设计者之间的一种协定(agreement)。它指定了CTS的一个子集和一个用法常规(usage conventions)集;

l metadata(元数据)——描述和引用CTS所定义类型的数据。元数据被以一种独立于任何特定的程序设计语言的方式存储。从而,元数据为操作程序的工具(如编译器和调试器)之间,以及这些工具和VES之间提供了一种公共交换机制。

l VESVirtual Execution System虚拟执行系统)——该系统实现和实施CTS模型。VES负责装入和运行为CLI编写的程序。它在运行时,利用元数据将分开产生的模型连接在一起,并为执行托管代码和数据提供所需要的服务。VES也被称为执行引擎;

l CILCommon Intermediate Language公共中间语言)——可被VES理解的指令集,也被称为MSIL(微软IL)。

 

程序集(Assembly,装配/汇编)就是CLR中的组件,它是一种功能上不可分割的逻辑单元,由一个或多个模块(moduleDLLEXE文件)组成。大多数程序集就是一个DLL,所以程序集也被称为“托管DLL”。

每个程序集中有一个程序清单(manifest),它包含了程序集内所有模块和其他文件的信息(如程序集的名称、版本号、文化和语言、程序集包含的所有文件列表、程序集所依赖的其他程序集等)。

程序集中自然包含了若干CLR类的(MSIL中间语言)代码,同时还包含了这些类的元数据。元数据(metadata)描述模块中类型的相关信息,如类型的名称、类型的可见性(publicassembly)、基类、实现的接口和方法、暴露的属性、提供的事件等。

COM相比,CLR的组件技术有了质的飞跃,前面提到的各种COM问题都迎刃而解、一扫而光。

 

l 相同点——约定(类型)

COM平台一样,CLR也注意组件间的约定,而且这些约定也是基于类型的(注意,组件技术里的类型是广义的,除了包括字符、布尔、整数和浮点数等基本数据类型之外,还包括类、结构、接口、串、数组、枚举、委托[delegate,指向方法和函数的安全指针,用于事件处理和回调]等高级结构类型)。

 

l 不同点1——约定的描述(元数据)

但是与COM(没有标准格式来描述约定)不同的是,CLR有完全规范的格式来描述组件之间的约定——元数据(metadata)。CLR的元数据是机器可读的,其格式是公开的、国际标准化的、完全规范的。CLR还提供了读写元数据的实用工具,使用者不需要了解元数据的底层文件格式。

不像COM的元数据(IDLTLB)难以定制和扩展;而且其元数据中又缺少依赖和版本信息,使得对组件的部署和版本的控制都十分困难;另外,COM元数据的存在是可选的,而且经常会被忽略掉,这对组件应用的构建会造成很多问题。

CLR通过定制(本身就是强类型的)特性(attribute),使其元数据可以达到清晰容易的可扩展性。CLR元数据中还包括组件的依赖关系和版本信息,从而允许使用新技术来处理版本控制问题。另外,CLR元数据的存在是强制性的,部署或加载组件都必须访问元数据。因此,构建基于CLR的基础架构和各种工具,显然要比COM容易的多。

 

l 不同点2——约定的类别(逻辑结构)

CLR约定与COM约定的第二个主要差别,是约定本身的特性。

COM中,组件的(二进制物理)约定隐含了:堆栈约定、虚函数表和(作为方法参数传递的)数据结构在内存中的表示形式。

CLR中,约定被描述为类型的逻辑结构,而不是物理的二进制格式。因此,在CLR的约定中,并没有暗示访问字段和方法的精确代码顺序。所以,在考虑虚方法布局、堆栈规则、对齐方式、以及参数传递方式时,CLR具有极大的灵活性。CLR是通过名字和签名来引用字段与方法,而不是偏移量。这样,CLR就避免了困扰COM的声明顺序问题,组件成员的实际地址/偏移量,需要等到运行时在类型被加载及初始化时,才能够确定。另外,CLR版本的改变(如从20021.02003年的1.1,再到2005年的2.0),也不会带来组件的重新编译。

 

l 不同点3——CIL

实现数据表示形式和方法地址的虚拟化,需要延时对约定的物理方面(如方法表和字段偏移量等)的解析,这就要求组件中不含具体的机器代码。基于CLR的组件,通过采用CILCommon Intermediate Language,公共中间语言)而实现了这一要求。

CIL是一组与处理器无关的指令集,它具有抽象能力——将与机器代码密切关联的物理数据的表示形式抽象出来。CIL使用的操作码在访问字段和调用方法时,不再使用绝对地址和偏移量,而是利用元数据进行基于名字和签名的引用。

CIL会在(第一次被)执行前被翻译成本地的机器语言,CLR执行的是由CIL生成的本地代码。而CLRCIL杯翻译成本机代码之前,是不会解析其物理绑定的细节的。由于翻译工作是在部署机器上进行的,所以,组件所需的外部类型定义,将与部署机器上的某个类型匹配,而不是开发者的机器。这极大减少了跨组件约定的不可靠性,同时又不会降低代码的运行性能。

另外,由于CIL到机器代码的翻译,发生在部署的机器上。所以,任何用到的待定处理器布局或对齐规则,都将与(代码将在其上面运行的)目标处理器架构相匹配。现在,软件正面临着一次重大的处理器迁移,即从IA-32/PentiumAMD32架构向IA-64/ItaniumAMD64架构的发展。对于这次升级,CLR显得尤为重要。

 

l COMCLR过渡

鉴于COM技术已经被使用多年,有许多现存的资源,程序员和用户也不可能一下子就全部完全转换到.NET环境。因此,微软公司也允许在CLR环境中继续使用COM/DCOM/ COM+DNA,这可以通过.NET框架的 System.EnterpriseServices 命名空间来进行。

但是鉴于与COM相比,CLR组件所具有的无比优越性。COM技术必然会走向灭亡,而.NETCLR终将取而代之。