当前位置: 首页 > 图文教程 > 网络编程 > ASP > 浅析COM的思想及原理(2)

ASP
对数据库中的记录用上一条下一条显示(二)
对数据库中的记录用上一条下一条显示(三)
完整的站点访问统计系统(一:数据库篇)
FIF小组ASP互动视频教程
关于ASP,ASP.NET,VB.NET里的MD5加密函数
ASP正则表达式详解
ASP中非数据库实现数据对象的定义及处理
编程爱好者的福音 让IIS6.0支持ASP
使用xml http为网站增加域名查询功能
用ASP实现支持附件的EMail系统
使用ADO.net将数据导出到Excel并提供下载
ASP实现图片上传
asp组件上传
ASPX页Web服务调用性能优化
asp实现语音上传
VBScript教程 第六课
VBScript教程 第三课
使ASP程序跨浏览器
四步讲解ASP中正则表达式的应用
ASP教程:深入认识学习ASP应用Cookies的技巧

ASP 中的 浅析COM的思想及原理(2)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-03   浏览: 35 ::
收藏到网摘: n/a

  三、COM中的几个重要概念

  1、组件:

  其实只要你仔细阅读了前面的部分,组件的概念应该已经很清楚了。这里所说的组件,就是前面反复在讨论的所谓“模块”。现在我只想强调一下组件需要满足的一些条件。首先是封装性,组件必须向外部隐藏其内部的实现细节,使从外部所能看到的只是接口。然后是组件必须能动态链接到一起,而不必像面向对象中的class一样必须重新编译。

  2、接口:

    由于组件向外部隐藏了其内部的细节,因此客户要使用组件时就必须通过一定的机制,也就是说要通过一定的方法来实现客户与组件之间的通信,这就需要接口。所谓接口就是组件对外暴露的、向外部客户提供服务的“连接点”。外部的客户见不到组件内部的细节,它所能看到的只是接口,客户也是通过接口来获取组件提供的服务。这有点像OSI网络协议分层模型,每一层就像一个组件,它内部的实现细节对于其他层是不可见的;而每一层通过“服务接入点”向其上层提供服务,这就像这里所说的接口。一般来说,接口总是固定的,也是公开的。组件的开发人员要实现这些接口,而客户则通过接口获得服务。正是接口的这种固定和公开,才使得组件和客户能够在不了解对方的情况下达成一致。

  3、客户:

  这里所说的客户不是指使用软件的用户,而是指要使用某一个组件的程序或模块。也就是说,这里的客户是相对组件来说的。

  四、COM的实现原理与雏形模拟

  COM编程的一个重要特点就是要模块化,说得具体一些,就是要将客户和组件分隔开来,而客户和组件之间又是通过接口来通信的。下面,我就介绍一下COM是怎样将客户与组件分隔开来,又是怎样利用接口来实现客户与组件间的通信的。

  首先我要讲讲接口。COM中的接口实际上是一个函数地址表,当组件实现了这个接口后,这个函数地址表中就填满了组件所实现的那些接口函数的地址。而客户也就是通过这个函数地址表获得组件中那些接口函数的指针,从而获得组件所提供的服务的。从某种意义上说,我们可以把接口理解为c++中的虚拟基类;或者说,在c++中可以用虚拟基类来实现接口!这是因为COM中规定的接口的存储结构,和c++中的虚拟基类在内存中的结构是一致的。其存储结构如下图:  
 
                                         虚函数表
               vtbl指针------>Fun1()指针-------->
                                       Fun2()指针-------->
                                       Fun3()指针-------->
                                       …………
  
  Vtbl指针指向一个虚函数表,而这个虚函数表的表项就是指向这些虚函数的指针。

  接口有了,那么组件又是怎样实现接口的呢?实际上,如果用虚拟基类来实现接口,那么组件就是对这个虚拟基类的继承。大家知道,当某个类继承于一个虚拟基类的时候,它就要实现这个虚拟基类里声明的虚函数,这就正好与组件实现接口这一点相吻合。举一个例子来说明,有一个接口InterfaceA,组件ComponentB要实现这个接口,那么就可以这样用c++语言来描述:

//接口:
class InterfaceA
{
  virtual void Fun1()=0;
  virtual void Fun2()=0;
};
//实现了接口InterfaceA的组件:
class ComponentB: public InterfaceA
{
  virtual void Fun1()
  {
     printf("Fun1\n");
  }
  virtual void Fun2()
  {
     printf("Fun2\n");
  }
};

  而客户只需要得到一个指向ComponentB实体的InterfaceA指针就可以获得ComponentB组件的服务了:

//使用了组件ComponentB的客户:
……
ComponentB CB;
InterfaceA *pIA=&CB;  //获得指向ComponentB实体的InterfaceA指针,以下客户就可以只通过接