什么是COM?(转)

来源:互联网 发布:sql截取字符串前几位 编辑:程序博客网 时间:2024/05/19 03:20

在讨论COM以前,我们得认识到一个事实,编写软件实际上是一个非常耗费时间和金钱的活动,所以人们不断寻找方法以减少这些花费,一个很重要的就是“软件重用”。在一个理想的环境下,我们应该能够编写一次代码,在任何地方都可以运行,即使这个环境编写者都没有想到过。当一个程序员修改了自己发布给别人使用的函数功能后,使用者应该不需要改变或者重新编译程序就可以使用这个功能。
早期的努力是使用类库,这个工作在C++中比较常见,但是这种做法是有很大缺陷的,要共享C++的二进制代码是非常困难的。为了解决这个问题,程序员们试图建立一种标准去达到软件在二进制级别上的共用。
Components Object Model (COM) 是软件组件互相通讯的一种方式。它是一种二进制和网络标准,允许任意两个组件互相通讯,而不管它们是在什么计算机上运行(只要计算机是相连的),不管各计算机运行的是什么操作系统(只要该系统支持 COM),也不管该组件是用什么语言编写的。COM 还提供了位置透明性:当您编写组件时,其他组件是进程内 DLL、本地 EXE 还是位于其他计算机上的组件,对您而言都无所谓。COM 是基于对象的——但是这种对象概念与您熟悉的 C++ 或 Visual Basic 中的对象不太一样。
首先,COM 对象被很好地封装起来。您无法访问对象的内部实现细节;您无法知道对象使用了什么数据结构。实际上,对象的封装是如此的严密,以致于 COM 对象通常被描绘为盒子。细节是不会告诉你的,但是我们可以通过接口来访问COM对象里面的方法,当然如果COM组件提供商肯告诉你那些接口中的函数和属性起什么作用的话。
概括地说,COM具有如下一些优越性:
编程技术难度和工作量降低,开发周期变短,开发成本降低。一般编程人员只须根据应用功能要求选用合适的组件,而不必事无巨细都自己动手去完成。组件模块将编程的技术难度和工作量在人员个体和时间上进行了分摊。我们使用ESRI的COM组件编写程序就属于这一级别。
实现分层次的编程,从而促进了软件的专业化生产。专业人员可以开发出具有很强专业性的软件组件,这样既保证了普通的编程应用人员能够完成所需要的应用开发,又不至于降低使用的性能。应用人员不便实现的组件模块可以让专业人员定做。ESRI的程序员们使用C语言为我们辨析了一个个COM组件给我们使用。
软件的复用率提高,使软件的使用效率得到提高并延长了使用寿命。组件编程体系使大量的编程问题局部化了,使软件的更新和维护变得快速和容易,软件的成本大大降低。新的函数功能如果在接口没有改变的情况下很容易使用。

  
  COM 这是微软为了解决代码重用的一个重要机制。重用代码的最简单办法是源代码重用,把写好的函数和类加到自己当前的代码中,编译即可。简单是简单,敝病却显然的多。另一个常用的方法是单独做成模块,以DLL的形式分发,DLL导出函数或者类,客户程序用动态/静态链接的方法将其加载,这显然比前一种源代码的方法好一些,难度也不大,最为常用。但DLL也有一些不足,最根本的,它不是二进制兼容,DLL版本升级一次就需要与客户程序代码重链接一次,有些时候这几乎是不可能的任务。为了更好地让编程像“搭积木”一样简单,让模块可以完美地配合,完美地替换,COM产生了。COM不是类库,不是代码,不是操作系统的服务,而是一套编程模型,理论上来说,它与语言无关,与操作系统无关,unix下同样可以做COM。COM是一种程序结构模型标准,你做的DLL或EXE在结构上满足这么一个标准,那这个DLL或EXE就是一个组件,它将在该平台上成为二进制兼容。COM主要利用了注册表来登记本模块的信息。客户程序调用时首先查注册表,找到所需组件的位置(这实现了位置透明),然后就用Loadlibrary把它加载进来,这和普通调用没有本质区别,区别在于由于组件特殊的实现方法使得整个过程中用户程序都不知道组件的位置,组件的类的实例化过程,如何销毁,不能直接访问组件的任何实现细节,用户只与组件的几个 public接口打交道。这将实现真正的模块之间的独立。对用户程序而言,对于目标组件的认识,除了接口,一无所知。在接口不变的情况下,组件可任 意替换而客户程序不作任何改动,无需编译,仅这一点,在中大型程序的模块集成的过程中就将节约相当多的时间。 "STL": Standard Template Library,标准模板库
  这是最早由Alexander Stepanov和Meng Lee(蛮像中国人的名字)完成,于1994年提交给ANSI/ISO 标准C++委员会并通过而成为标准C++的一部分。望文生义即可知这是一个代码库标准,不是语法标准。简单地说,STL是以C++中的模板语法为基础建立起来的一套包含基础数据结构和算法的代码库。STL的特点是实现了“类型参数化”,即STL的代码中可处理任意自定义类型的对象,如果不使用模板技术的话,这是一件相当困难的事。也因为这个原因,在最新的java及C#语法中均加入了对模板语法的支持,可见其重要性。另外一个有关STL重要的话题是GP (Generic Programming),泛型。这是与面向对象相并列的另外的一个编程模型,它以模板为基础,弱化了实体类型的差异,简化了编程时问题抽象的模型,提供了更好的封装性和弹性,对于繁杂的面向对象编程毫无疑问是一种解脱,至少是精神上的。GP并不是用来取代面向对象的,而是作为一个有益的补充体,是面向对象很好的合作伙伴。GP是最近几年软件架构的一个研究热点,但国内真正的应用似乎并不多见,这项技术本身还基本处于研究前沿。< <Modern C++ Design>>一书对C++中的GP应用有很好的诠释,而这本书对脑细胞的杀伤力之大,也是其它C++书藉望尘莫及的。想知道C++的代码技巧可以做到怎样的出神入化吗?不妨看看这本书。

谈了这么多COM的好处,我们该讲点技术型的东西了,我们在AO编程中需要那些COM知识呢?
1. COM不是接口,也不是对象,它是一种标准。
2. 符合COM标准的对象就是我们要谈论的重点——COM对象。其实COM对象也无非是实现了很多接口的对象而已。
3. COM对象必须实现Iunknown接口,这个接口是管理COM对象生命周期的,当COM对象不使用的时候,是这个接口定义的方法负责释放内存。一个COM对象可以没有任何别的接口,但是这个必须要,它是默认实现的接口。
4. QI,即所谓查询接口。由于COM对象有很多个接口,不同的接口管理着COM的不同类型的方法,因此从一个接口可以使用的方法转到另一个接口可以使用的方法的过程称为QI,这个过程是由Idispatch接口管理的。
5. GUIDs 每个组件都有一个独一无二的标识,这就是所谓的广泛唯一标识符。这个标识符就是COM组件的身份,它是一个128bits的数字,由系统自由分配,不要担心这个标识会有重复的一天。如果我们每秒产生1000万个UID,那么到5770年才可能遇到重复。别告诉我那个时候我们还使用WINDOWS的玩意。
6. 一个COM对象可以有多个接口,一个接口也完全可以被多个COM对象实现。
7. 接口分为两种,内置接口和外置接口。前一种定义的是COM对象的方法和属性,用implements实现,COM对象必须实现所有的接口内容;后一种定义的是COM对象的事件,用withEvents实现,这种接口在实现的时候不必实现所有的内容。
8. COM组件必须被注册后才能使用,它得到注册表那里去登记“户口”。
       COM组件很不错,可是它也有致命的缺陷,这个缺陷就来自它本身。我们知道,COM是可以被重用     的,COM对象的实现过程也可以被修改升级(定义是不能修改的哦),如果两个程序都使用一个COM对象,而这个COM组件升级了的话,很可能就出现某个程序无法使用新组件的情况,这就被称为“DLL HELL(DLL灾难)”,我们有时候安装了新软件后很多别的软件都无法使用,很多原因就是因为这个DLL HELL。别以为这是个小问题,这可是人家微软提出.NET平台的一个主要原因。

原创粉丝点击