{C++} COM 组件多层聚合嵌套原理

简介:

 这个小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: 

复制代码
 1  HRESULT CC::QueryInterface( const  IID &  iid,  void   ** ppv)
 2  {
 3      printf( " ---------------------excute CompC QueryInterface!!!\n " );
 4       if  ( iid  ==  IID_OtherInterface ) 
 5      {
 6           if (m_pUnknownOuter  !=  NULL){
 7              printf( " CompC m_pUnknownOuter is not null!\n " );
 8               return  m_pUnknownOuter -> QueryInterface(iid, ppv);
 9          } else {
10               return  NondelegationQueryInterface(iid, ppv);
11          }
12      }
13       if  ( iid  ==  IID_SomeInterface ) {
14           if   ( m_pUnknownInner  !=  NULL ){
15              printf( " CompC m_pUnknownInner is not null!\n " );
16               return  m_pUnknownInner -> QueryInterface(iid, ppv);
17          }  else {
18               return  NondelegationQueryInterface(iid, ppv);
19          }
20      }  else  {
21           return  NondelegationQueryInterface(iid, ppv);
22      }
23  }
复制代码

 

 NondelegationQueryInterface:

 

复制代码
 1  HRESULT CC::NondelegationQueryInterface( const  IID &  iid,  void   ** ppv)
 2  {
 3      printf( " ---------------------excute CompC NondelegationQueryInterface!!!\n " );
 4       if  ( iid  ==  IID_IUnknown )
 5      {
 6           * ppv  =  (INondelegatingUnknown  * this  ;
 7          ((IUnknown  * )( * ppv)) -> AddRef() ;
 8      }  else   if  ( iid  ==  IID_AnyInterface ) 
 9      {
10           * ppv  =  (IAnyInterface  * this  ;
11          ((IAnyInterface  * )( * ppv)) -> AddRef() ;
12      }  else   if  ( iid  ==  IID_SomeInterface ) 
13      {
14           return  m_pUnknownInner -> QueryInterface(iid, ppv) ;
15      }  else   if  ( iid  ==  IID_OtherInterface ) 
16      {
17           return  m_pUnknownOuter -> QueryInterface(iid, ppv) ;
18      }  else
19      {
20           * ppv  =  NULL;
21           return  E_NOINTERFACE ;
22      }
23       return  S_OK;
24  }
复制代码

 本文转自施杨博客园博客,原文链接:http://www.cnblogs.com/shiyangxt/archive/2010/12/04/1896398.html,如需转载请自行联系原作者

相关文章
|
编译器 Linux C语言
我的C++奇迹之旅相遇:支持函数重载的原理
我的C++奇迹之旅相遇:支持函数重载的原理
|
11月前
|
C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
161 4
|
11月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
201 3
|
11月前
|
存储 C语言 C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(一)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
217 2
|
7月前
|
安全 C语言 C++
彻底摘明白 C++ 的动态内存分配原理
大家好,我是V哥。C++的动态内存分配允许程序在运行时请求和释放内存,主要通过`new`/`delete`(用于对象)及`malloc`/`calloc`/`realloc`/`free`(继承自C语言)实现。`new`分配并初始化对象内存,`delete`释放并调用析构函数;而`malloc`等函数仅处理裸内存,不涉及构造与析构。掌握这些可有效管理内存,避免泄漏和悬空指针问题。智能指针如`std::unique_ptr`和`std::shared_ptr`能自动管理内存,确保异常安全。关注威哥爱编程,了解更多全栈开发技巧。 先赞再看后评论,腰缠万贯财进门。
331 0
|
小程序 编译器 Linux
C++ 异常原理:以一个小程序为例
作者在调查某个 bug 时涉及到 C++ 异常,借此机会以本文把 C++ 异常机制梳理清楚供大家参考。
|
存储 自然语言处理 安全
C++ STL标准库 《string原理与实战分析》
C++ STL标准库 《string原理与实战分析》
254 0
|
11月前
|
C++
C++番外篇——虚拟继承解决数据冗余和二义性的原理
C++番外篇——虚拟继承解决数据冗余和二义性的原理
119 1
|
11月前
|
缓存 Linux 编译器
【C++】CentOS环境搭建-安装log4cplus日志组件包及报错解决方案
通过上述步骤,您应该能够在CentOS环境中成功安装并使用log4cplus日志组件。面对任何安装或使用过程中出现的问题,仔细检查错误信息,对照提供的解决方案进行调整,通常都能找到合适的解决之道。log4cplus的强大功能将为您的项目提供灵活、高效的日志管理方案,助力软件开发与维护。
383 0
|
C++
C++ Qt开发:QUdpSocket网络通信组件
QUdpSocket是Qt网络编程中一个非常有用的组件,它提供了在UDP协议下进行数据发送和接收的能力。通过简单的方法和信号,可以轻松实现基于UDP的网络通信。不过,需要注意的是,UDP协议本身不保证数据的可靠传输,因此在使用QUdpSocket时,可能需要在应用层实现一些机制来保证数据的完整性和顺序,或者选择在适用的场景下使用UDP协议。
641 2