COM的通信原理及ATL的通信操作

一、             COM的通信原理

1、  通信模型:一般,我们只使用客户端程序到组件的通信,并且这种通信是通过组件的接口来实现的。现在,我们讲一下服务器到客户端之间如何打开一个双向通信通道,并提供一个功能更加强大的通信环境。按下面的方法可以提供一个具备回调功能(或称通知)的组件:

a)         在一个组件中描述几个接口,其中一部分接口由组件实现(如IMath),一部分接口则由客户端程序实现(如ICallback)。

b)        在客户端程序中,使用自己喜欢的技术实现一个接口,并由组件来描述(如iCallback)。

c)        组件在其中的一个入站接口上实现一个方法(如IMath::Advise),客户端程序可以通过该方法传送它的一个接口指针(ICallback)。

d)              然后组件通过客户端实现的接口调用接口方法,为客户端程序提供通知消息。

2、  引入和引出接口

COM使用incoming interface(引入接口)和outing interface(引出接口)两个术语,来描述组件可以支持的两种不同类型的接口。一个引入接口是指由组件实现的接口,如IMath是个引入接口,因为它是由你的组件来实现的。一个引出接口是指在组件的类型库中描述的接口,但是它实际上是由math组件的客户端程序实现的。

3、  示例

interface ICallback:IDispatch

[

[id(1),helpstring("显示求和结果")] HRESULT Show([in] long sum);

]

interface IMath:IDispatch

[

[id(1),helpstring("求和并显示")] HRESULT Add([in] long num1,[in] long num2,[out,retval] long* ret);

[id(2),helpstring("添加引出接口") HRESULT Advise([in] ICallback* pCallback);

[id(3),helpstring("释放接口") HRESULT Unadvise();

]

class CMath:IMath

{

CComPtr<ICallback> m_pCallback;

STDMETHODIMP Add(long num1,long num2)

{

long ret=num1+num2;

if(m_pCallback)

m_pCallback->Show(ret);

return S_OK;

}

STDMETHODIMP Advise(ICallback* pCallback)

{

m_pCallback=pCallback;

pCallback->AddRef();

return S_OK;

}

STDMETHODIMP Unadvise()

{

m_pCallback->Release();

m_pCallback=0;

return S_OK;

}

}

客户端程序首先实现ICallback接口中的函数,并把ICallback的实现类通过Advise传给CMath,这样当进行加法时,就能通知客户端了,这就是COM的通信原理。

二、             ATL通信方法

ATL提供了IDispEventSimpleImpl和IDispEventImpl两个模板类,这两个模板类可用于在 ATL 类中提供连接点接收器支持,为事件调度接口提供了实现,我们只需要对要接收的事件方法提供实现。这些连接点接收器是用事件接收映射(由类提供)来映射的。

1           若要正确地实现类的连接点接收器,必须完成以下步骤:

1.1         为每个外部对象导入类型库 (如:#import "progid:SendEvent.MyMath" raw_interfaces_only, no_namespace, named_guids),

1.2         继承 IDispEventImpl接口(如public:IDispEventSimpleImpl<1,CSumDlg,&DIID_IMathEvents>),

或 继承IDispEventSimpleImpl 接口(如IDispEventImpl<1,CSumDlg,&DIID_IMathEvents,&LIBID_SendEvent,1,0>)。

1.3         声明事件接收映射 ,在类中添加BEGIN_SINK_MAP(classname)、END_SINK_MAP()宏,

1.4         IDispEventSimpleImpl都必须添加一个宏SINK_ENTRY_INFO去实现事件接收映射。如:

BEGIN_SINK_MAP(CSumDlg)

SINK_ENTRY_INFO(1,DIID_IMathEvents,1,OnShow,&ShowInfo)

END_SINK_MAP()

1.5            IDispEventImpl都必须添加一个宏SINK_ENTRY或SINK_ENTRY_EX去实现事件接收映射。如

BEGIN_SINK_MAP(CSumDlg)

SINK_ENTRY_EX(1,DIID_IMathEvents,1,OnShow)

END_SINK_MAP()

1.6         实现事件处理函数,如实现OnShow函数。

1.7         通知(调用DispEventAdvise与数据源建立连接)。

1.8         和取消通知连接点 (调用DispEventUnadvise断开连接)。

2           详细解析

2.1         IDispEventImpl继承于IDispEventSimpleImpl,他们的大部分功能是相同的,区别仅在于IDispEventImp是从类型库中获取接口信息,而IDispEventSimpleImp是通过一个指向SINK_ENTRY_INFO结构体的指针获得事件信息。

2.2            IDispEventImpl和IDispEventSimpleImpl的参数分别为

IDispEventImpl<
   UINT nID,
   class T,
   const IID* pdiid = &IID_NULL,
   const GUID* plibid = &GUID_NULL,
   WORD wMajor = 0,
   WORD wMinor = 0,
   class tihclass = CcomTypeInfoHolder
>
IDispEventSimpleImpl<
   UINT nID,
   class T,
   const IID* pdiid
>
其中,
nID:唯一标识数据源对象的标志;
T:从IDispEventImpl/ IDispEventSimpleImpl派生的类;
pdiid:要接收的事件调度接口的DIID指针;
plibid:定义了事件接口的类型库的LIBID指针;
wMajor:类型库的主版本号;
wMinor:类型库的次版本号;
tihclass:管理T类的类型信息的类(一般用默认)

2.3         宏的操作

2.3.1       事件接收映射必须以BEGIN_SINK_MAP(class)开头,以END_SINK_MAP()结尾,其中class是接收事件的类。

2.3.2       SINK_ENTRY_INFO、SINK_ENTRY_INFO和SINK_ENTRY的关系为

SINK_ENTRY_INFO(id, iid, dispid, fn, info)

#define SINK_ENTRY_EX(id, iid, dispid, fn) SINK_ENTRY_INFO(id, iid, dispid, fn, NULL)

#define SINK_ENTRY(id, dispid, fn) SINK_ENTRY_EX(id, IID_NULL, dispid, fn)

其中,

id:唯一标识数据源对象的标志,与模板类的第一个参数对应;

iid::要接收的事件调度接口的DIID指针;

dispid:事件的调度ID,与接口中方法的ID对应;

fn:事件处理函数;

info:SINK_ENTRY_INFO结构体的指针,主要包括事件的参数和返回值信息。

COM的通信原理及ATL的通信操作 看过的一篇非常好的讲解通讯机制的文章相关推荐

  1. 基于Matlab的模拟通信实验平台设计,【通信原理仿真实验】通信原理虚拟实验仿真平台的设计和实现_玛雅作文网...

    作文「通信原理虚拟实验仿真平台的设计和实现」共有 4564 个字,其中有 2704 个汉字,1316 个英文,162 个数字,382 个标点符号.作者佚名,请您欣赏.玛雅作文网荟萃众多优秀学生作文,如 ...

  2. 通信原理眼图画法_通信原理课程总结(二)

    在上一篇文章中,我把通信原理中的基础知识已经总结完毕,以后的内容就是利用前边的基础知识来进行更深层次的学习了,引出了通信原理中非常重要的一部分--调制与解调. 首先调制之所以重要,是因为: 调制可以把 ...

  3. 基于matlab的通信原理,基于Matlab的通信原理

    基于Matlab的通信原理Tag内容描述: 1.基于基于 MATLABMATLAB 的眼图仿真的眼图仿真 及其与通信实验箱之结果的比较及其与通信实验箱之结果的比较 摘要摘要 通信实验往往可以从硬件和软 ...

  4. matlab通信原理实验低频高频,通信原理实验一 模拟调制已调信号的波形和频谱.doc...

    通信原理实验一 模拟调制已调信号的波形和频谱.doc (17页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 14.90 积分 <通信原理>课 ...

  5. 服务器客户端通信原理,客户端到服务器端通信原理

    我们首先要了解一个概念性的词汇:Socket socket的英文原义是"孔"或"插座".作为进程通信机制,取后一种意思.通常也称作"套接字" ...

  6. 一文总结GaussDB通信原理知识

    摘要:从发展历程到通信模型设计,到你了解一下GaussDB通信原理知识. MPPDB通信库发展历程 Postgres-XC 方法:采用libpq通信库实现CN和DN之间的连接,CN负责计算,DN仅进行 ...

  7. nacis服务注册原理_HwServiceManager篇Android10.0 HwBinder通信原理(五)

    阅读本文大约需要花费34分钟. 原创不易,如果您觉得有点用,希望可以随手转发或者点击右下角的 "在看".""分享"",拜谢! <And ...

  8. matlab 2ask,(最新整理)基于MATLAB的2ASK和2FSK调制仿真(通信原理实验报告)

    <(最新整理)基于MATLAB的2ASK和2FSK调制仿真(通信原理实验报告)>由会员分享,可在线阅读,更多相关<(最新整理)基于MATLAB的2ASK和2FSK调制仿真(通信原理实 ...

  9. 2psk系统的仿真课程设计matlab,通信原理课程设计-基于MATLAB-Simulink的2PSK仿真

    <通信原理课程设计-基于MATLAB-Simulink的2PSK仿真>由会员分享,可在线阅读,更多相关<通信原理课程设计-基于MATLAB-Simulink的2PSK仿真(17页珍藏 ...

最新文章

  1. 零基础Python培训入门 教你认识下这些基础内容
  2. [原]Failed to load SELinux policy. System Freezing ----redhat7or CentOS7 bug
  3. 基于 Laravel、Vue.js开发的全新社交系统----ThinkSNS+
  4. 【转】IT名企面试:腾讯笔试题(2)
  5. 加密、解密、摘要、签名、证书一文搞懂
  6. [转]JS调用Android里面的方法,Android调用JS里面的方法
  7. 数据结构-查找-总结归纳知识点
  8. 9202 myslq 课堂笔记 dml dql
  9. Linux下创建指定路径下的文件夹/文件,通过get_option()传递路径
  10. 凸优化第七章统计估计 7.5实验设计
  11. 18650锂电池充电方案及保护板电路构思
  12. 百度地图实现定位功能及城市选择
  13. 省市县联动列表html代码,若依添加省市县联动三级菜单
  14. verilog语法错误
  15. THINKPHP官方推荐第三方插件库
  16. 深信服连接openldap_深信服AC结合第三方服务器AD域认证
  17. 深度解析IPFS是什么
  18. 名帖109 鲜于枢 小楷《老子道德经卷》
  19. 我国超级计算机历代,《决战崛起——中国超算强国之路》作品研讨会召开
  20. PYNQ-overlay

热门文章

  1. 高考数学复习:任意角、弧度制及任意角的三角函数(解析版一轮复习)
  2. C#Invoke和BeginInvoke应用详解
  3. 教你如何将电脑瞬间关掉
  4. 交换机和路由器的区别在哪里
  5. #pragma命令详解
  6. 67行代码实现:模拟手机九宫格输入法
  7. 《Python入门》Windows 7下Python Web开发环境搭建笔记
  8. 卖女装用什么产品做吸粉?吸粉方法要按照哪些步骤来做呢?
  9. Git管理代码:分支使用(五)
  10. 再见了, VS Code!文末有彩蛋!