分享
 
 
 

用ATL建立轻量级的COM对象(八)

王朝vc·作者佚名  2006-01-17
窄屏简体版  字體: |||超大  

用ATL建立轻量级的COM对象

第八部分

作者:赵湘宁

第一部分:为什么要使用ATL。

第二部分:起步篇。

第三部分:实现IUnknown。

第四部分:实现接口。

第五部分:不要过分抽象。

第六部分:输出你的类。

第七部分:ATL和注册表。

连接

COM

编程最单调乏味的一个方面是使用连接点来支持 outbound

接口。IConnectionPoint/IConnectionPointContainer

的设计好像是专门用来解决这个问题的,但是经验证明,不论是在性能方面,还是在易用性方面,它还是存在不足之处。ATL为每一个这样的接口提供了缺省的实现类,多少解决了一些易用性问题。

要理解ATL如何实现连结点,最容易的方式是看例子:假设定义了如下的

outbound 接口:

interface IPageSink : IUnknown {

HRESULT OnPageReceived(void);

}

interface IStopSink : IUnknown {

HRESULT OnShutdown(void);

}

为了支持这两个 outbound 接口,下面的ATL代码已经足够:

class CPager

: public CComObjectRoot,

public CComCoClass,

public IPager,

public IConnectionPointContainerImpl,

public IConnectionPointImpl,

public IConnectionPointImpl

{

BEGIN_COM_MAP(CPager)

COM_INTERFACE_ENTRY(IPager)

COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)

END_COM_MAP()

BEGIN_CONNECTION_POINT_MAP(CPager)

CONNECTION_POINT_ENTRY(IID_IPageSink)

CONNECTION_POINT_ENTRY(IID_IStopSink)

END_CONNECTION_POINT_MAP()

};

大多数有经验的 COM

程序员首先注意到的是 CPager 类从一个接口(IConnectionPoint)派生的,这个接口并不作为

COM 本身的一部分提供。为了实现这种诀窍,ATL 类 IConnectionPointImpl

不从接口 IConnectionPoint 派生,而是象 IConnectionPoint

那样以相同的顺序定义它的虚函数。

其次,为了防止每一个基类继承主对象的 QueryInterface

实现,IConnectionPointImpl中第一个虚函数不是QueryInterface。而是一个类型兼容的方法,它叫做

LocCPQueryInterface,这个方法只针对 IID_IConnectionPoint 和 IID_IUnknown。它除了涉及允许完全基于多线程实现外,还有许多深奥的窍门在里面。

对象的 FindConnectionPoint 方法实现使用由 ATL中

CONNECTION_POINT

宏定义的连接点映射。此映射是对象中的一个 DWORD表,表示与

IConnectionPoint 实现相对应的偏移量。FindConnectionPoint

遍历此偏移量数组,询问每一个所碰到的连接点,看看此连接是否拥有所请求的接口。

上述例子建立了一个有效的对象实现,它支持作为

outbound 接口的 IStopSink 和 IPageSink 。但是,为了调用outbound

接口,你需要存取由 IConnectionPointImpl

类操纵的接口指针向量,并自己手动模拟多点传送:

typedef IConnectionPointImpl base;

for (IUnknown** pp = base::m_vec.begin();

pp OnPageRecieved();

编写多点传送例程十分繁琐。所幸的是,ATL提供了 Visual Studio

组件—— ATL 代理产生器(ATL Proxy Generator),(如下图五)它们会读取接口的类型库描述并产生

IConnectionPointImpl 派生类,为每一个 outbound

方法添加适当的 Fire 例程。连结点代理便被产生出来。

图五 ATL 代理产生器

这个类的定义应该像下面这样:

class CPager

: public CComObjectRoot,

public CComCoClass,

public IPager,

public IConnectionPointContainerImpl,

public CProxyIPageSink,

public CProxyIStopSink

{

BEGIN_COM_MAP(CPager)

COM_INTERFACE_ENTRY(IPager)

COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)

END_COM_MAP()

BEGIN_CONNECTION_POINT_MAP(CPager)

CONNECTION_POINT_ENTRY(IID_IPageSink)

CONNECTION_POINT_ENTRY(IID_IStopSink)

END_CONNECTION_POINT_MAP()

};

为了发送出境方法通知,你只要调用适当的Fire_XXX方法即可:

STDMETHODIMP CPager::SendMessage(LPCOLESTR pwsz) {

// send outbound notifications

HRESULT hr = Fire_OnPageRecieved();

// process normally

return hr;

}

机器产生代理的一个限制是必须要 outbound

接口的类型库定义。对于大量的 COM

接口而言,这是不可能的,因为类型库在转换方面与 IDL 特性背道而驰。对于更复杂的接口,你可以从机器所产生的代理开始并修改这些代码来进行尝试。

后记

本文概括地讨论了 ATL

核心体系结构,主要针对 ATL 中使用,同时也是 ATL

用户使用的基本编程风格。实际上本文中所讨论的和涉及的内容特性都是基于

ATL1.1 版本的,某些内容在 ATL2.0

中稍有改动。本文没有包含有关ActiveX

控件接口的缺省实现方面的内容,它们被加到了 ATL2.0

版本中,遵循与 ATL1.1 同样的编程哲学。只要你常常推敲

ATL 源代码,这些接口会很容易理解。

在与同事和朋友讨论 ATL

时,我发现大多数人的感触是针对 ATL

的设计。有一小部分人觉得它非常棒。另外一小部分人觉得它复杂而不可思议。但大多数人(包括我自己)的感觉是双重的,优劣兼而有之。幸运的是

ATL 编程是一个非常"量入为出"的过程。只要你去学总会有收获,所以初学者需要努力而为之。(全文完)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有