分享
 
 
 

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

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

用ATL建立轻量级的COM对象

第五部分

作者:赵湘宁

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

第二部分:起步篇。

第三部分:实现IUnknown。

第四部分:实现接口。

不要过分抽象

ATL最不直观的一个方面是你所定义和实现的C++类仍然是抽象基类。没错,在ATL的模板类和宏上辛苦了半天,却仍然得不到一个可以实例化的类。即使你从

CComObjectRootEx 派生,其结果同从一个或更多的ATL接口实现继承一样。从技术上讲,你的对象不提供

IUnknown 三个核心方法(QueryInterface,AddRef 和 Release)的实现。如果你检查现有ATL之前的 COM

实现,如果不是全部,那么也是大多数的方法实现并不在乎这个类是不是被用于COM聚合或tear-off,是不是被用于独立的对象或一个包含在内的数据成员,是不是要作为基于堆的对象或作为全局变量,以及是不是对象存在时,一直要保持服务器运行。为了允许最大限度的灵活性,所有这些方面分别通过ATL家族中的十个类属的

CComObject 之一来说明。参见下表:

类名

服务器是否加锁

是否代理IUnknown

是否删除对象

备注

CComObject

Yes

No

Yes

常规情况

CComObjectCached

Yes(在第二次AddRef之后)

No

Yes

用于通过内部指针控制的对象

CComObjectNoLock

No

No

Yes

用于不控制服务器运行的对象

CComObjectGlobal

Yes(在第一次AddRef之后)

No

No

用于全程变量

CComObjectStack

No

No

No

用于不能被增加引用计数的基于堆栈的变量

CComContainedObject

No

Yes

No

用于MFC风格的嵌套类

CComAggObject

Yes

Yes

Yes

仅用于聚合实现

CComPolyObject

Yes

Yes(如果聚合)

Yes

用于聚合/非聚合实现

CComTearOffObject

No

Yes(仅用于QueryInterface)

Yes

用于每次请求所创建的tear-offs

CComCachedTearOffObject

No

Yes(通过第二个IUnknown)

Yes

用于在第一次请求和缓存时所创建的tear-offs

每一个 CComObject 类用派生来提供正确的 QueryInterface,AddRef

和 Release 实现。如果QueryInterface,AddRef 和 Release的语义正确,则所有

CComObject

类用你的类名作为模板参数并创建一个从你的类派生的新类。在这些类中,CComObjectNoLock

是最容易理解的一个类。请看其代码:

template

class CComObjectNoLock : public Base {

public:

typedef Base _BaseClass;

CComObjectNoLock(void* = NULL){}

~CComObjectNoLock() {m_dwRef = 1L; FinalRelease();}

STDMETHOD_(ULONG, AddRef)() {return InternalAddRef();}

STDMETHOD_(ULONG, Release)() {

ULONG l = InternalRelease();

if (l == 0)

delete this;

return l;

}

STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)

{return _InternalQueryInterface(iid, ppvObject);}

};

template

class CComObject : public Base {

public:

typedef Base _BaseClass;

CComObject(void* = NULL) { _Module.Lock(); }

~CComObject() {m_dwRef = 1L; FinalRelease(); _Module.Unlock();

}

STDMETHOD_(ULONG, AddRef)() {return InternalAddRef();}

STDMETHOD_(ULONG, Release)() {

ULONG l = InternalRelease();

if (l == 0)

delete this;

return l;

}

STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)

{return _InternalQueryInterface(iid, ppvObject);}

static HRESULT WINAPI CreateInstance(CComObject** pp);

};

它假设你的对象将在堆中分配,也就是说最终调用

Release 时,将触发这个对象的 delete 操作。CComObjectNoLock

假设你的对象不是可聚合的,并且在服务器运行时,对象并不一直存在(因此有后缀

NoLock)。

为了在堆中分配基于 ATL 类的 CPager

实例,只要对这个类名进行 CComObject 模板包装即可:

IPager *p = new CComObjectNoLock();

CComObjectNoLock 类从 CPager

派生,并且添加了由 CPager 提供的使用 InternalQueryInterface,InternalAddRef

和 InternalRelease 的 QueryInterface,AddRef 和 Release实现。因为此对象是基于堆的,所以对

delete 的调用将发生在 CComObjectNoLock 类的 Release

实现中,此时InternalRelease 返回零。

CComObject

类通常被用于基于堆的对象,这个对象只要存在,则服务器一直要运行。与许多

CComObject 家族中的其它类一样,CComObject提供了一个全程变量,_Module,它有两个方法,Lock

和 Unlock。这些方法与 MFC 的 AfxOleLockApp 和AfxOleUnLockApp

很相似。CComObject 的构造函数调用_Module 的 Lock 方法,而 CComObject

的析构函数则调用_Module的Unlock 方法。ATL提供了一个 CComModule

类,它以适当的方式为进程内服务器实现了这些方法。当建立进程外服务器时,某个派生类(CExeModule)必须改写默认的

Lock / Unlock方法,以便以某种适当的方式下掉服务器。基于

AppWizard 的 ATL工程自动会有一个类用 PostThreadMessage

终止主线程的消息循环。(待续)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有