BK网络学院

首页搜索登录
首页业界网页平面多媒体程序数据库办公工具服务器系统网络安全站长认证壁纸
加入收藏 | 网站地图 | | RSS | WAP
你好,游客 登录 注册 搜索

COM 组件多层聚合嵌套原理

[日期:2010-12-04] 作者: 来源: [字体: ]

 大四的课还是蛮有意思的,其中有一个COM组件的课,感觉挺有收获,做了一个小Demo,是关于COM聚合的, 

 聚合和包容是COM的基本特征,老师上课没把这俩的关系讲清楚,也不大知道为啥放着简单的包容不用,用聚合写模块。

通过做这个Demo,俺算是理解了。因为包容只是单向调用接口,也就是从外到内,不能从内到外。而聚合则是双向调用的,

非常的灵活。下面通过具体的例子说说。

 

    这个小Demo是控制台调用三个动态链接库的,每个链接库中都有一个方法,最外面的库CompB.dll里面是减法运算, 

 聚合CompC.dll里面的乘法,CompC.dll聚合CompA.dll里面的加法。CompB.dll调用接口是OtherInterface,CompC.dll

调用接口是AnyInterface,CompA.dll调用接口是SomeInterface。 CompB内部指针Inner指向CompC,CompC内部指针 

Inner指向CompA,Outer指针指向CompB,CompA内部指针Outer指针指向CompC,通过这四个指针,可以使接口查询

双向传递。也就是说我可以通过OtherInterface拿到CompA的Add方法,也可以通过SomeInterface拿到CompB的Minus

方法,调用方式非常灵活。三个接口无论调用哪一个都可以访问到三个动态链接库中的所有方法。每一个方法都可以通过不同

接口调用,原理也很清晰和简单。多层聚合调用的中间层dll就需要一对指针指向上层dll和下层dll,就像CompC一样。实现也不

复杂,每个动态链接库都有一个查询接口方法,CompC和CompA通过非委托查询接口,进行调用传递。初始化过程是这样的,

CompB初始化CompC实例,CompC初始化CompA实例。CompB如果希望调用CompA就必须先初始化CompC,初始化过

程也很清晰。为了模块的灵活性,多写些代码还是值得滴。

基本原理如图:

 

我本地的执行输出: 

 

 

多层聚合嵌套核心方法是CompC的两个查询方法:

QueryInterface: 

  HRESULT CC::QueryInterface(const IID& iid, void **ppv)
  {
      printf("---------------------excute CompC QueryInterface!!!\n");
      if ( iid == IID_OtherInterface ) 
      {
          if(m_pUnknownOuter != NULL){
              printf("CompC m_pUnknownOuter is not null!\n");
              return m_pUnknownOuter->QueryInterface(iid, ppv);
          }else{
             return NondelegationQueryInterface(iid, ppv);
         }
     }
     if ( iid == IID_SomeInterface ) {
         if  ( m_pUnknownInner != NULL ){
             printf("CompC m_pUnknownInner is not null!\n");
             return m_pUnknownInner->QueryInterface(iid, ppv);
         } else{
             return NondelegationQueryInterface(iid, ppv);
         }
     } else {
         return NondelegationQueryInterface(iid, ppv);
     }
 }

NondelegationQueryInterface:

  HRESULT CC::NondelegationQueryInterface(const IID& iid, void **ppv)
  {
      printf("---------------------excute CompC NondelegationQueryInterface!!!\n");
      if ( iid == IID_IUnknown )
      {
          *ppv = (INondelegatingUnknown *this ;
          ((IUnknown *)(*ppv))->AddRef() ;
      } else if ( iid == IID_AnyInterface ) 
      {
         *ppv = (IAnyInterface *this ;
         ((IAnyInterface *)(*ppv))->AddRef() ;
     } else if ( iid == IID_SomeInterface ) 
     {
         return m_pUnknownInner->QueryInterface(iid, ppv) ;
     } else if ( iid == IID_OtherInterface ) 
     {
         return m_pUnknownOuter->QueryInterface(iid, ppv) ;
     } else
     {
         *ppv = NULL;
         return E_NOINTERFACE ;
     }
     return S_OK;
 }

关键词:COM  组件  嵌套  聚合  原理 

收藏 推荐 打印 | 录入:blue1000 | 阅读:
最新图文
本文评论   查看全部评论 (1)
表情: 姓名: 字数
点评:
       
评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事/刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款
第 1 楼
* 匿名 发表于 2015/4/30 22:17:59
wangdeshow@163.com 发个代码学习