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

ASP
构建你的网站新闻自动发布系统之三
构建你的网站新闻自动发布系统之四
如何用ASP编写网站统计系统一
如何用ASP编写网站统计系统二
如何用ASP编写网站统计系统三
如何用ASP编写网站统计系统四
ASP Error 0115的一些解决办法
ASP 3.0 新特色先睹为快(一)
ASP 3.0 新特色先睹为快(二)
ASP主件中的安全问题
一个汉字转成拼音的代码
使用w3Sockets组件实现域名查询功能
ASP中实现文件上传方法的研究
构建免受FSO组件威胁虚拟主机
用XMLHTTP做一个自己特色的Google
用asp实现的代码批量修改程序
无组件的数据库的备份与还原
用ASPJPEG组件制作图片的缩略图和加水印
解密ASP源代码
XmlHttp异步获取网站数据的例子

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-03   浏览: 81 ::
收藏到网摘: 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指针,以下客户就可以只通过接