Chinaunix首页 | 论坛 | 博客
  • 博客访问: 560005
  • 博文数量: 155
  • 博客积分: 4015
  • 博客等级: 上校
  • 技术积分: 1625
  • 用 户 组: 普通用户
  • 注册时间: 2005-11-18 16:55
文章分类

全部博文(155)

文章存档

2009年(20)

2008年(39)

2007年(66)

2006年(29)

2005年(1)

我的朋友

分类: WINDOWS

2007-07-01 17:11:53

  在写今天的文字前,我快速浏览了一下上回的《COM学习漫谈[1]》,这样可以让今天的“漫谈”,可以跟上回很好的接上,先把这叫做“圆谎”吧。还有一大喜事,我的《COM学习漫谈[1]》登上了CUBLOG的一周热点文章,好久没有上榜了,上次还是《TO_DATA使用详解》,事今已有一年之久吧。
  书接上回,今天我们来看看IUnknow接口,以及每个接口都必有[或曰:支持]的三个方法AddRef,Release,QueryInterface。我们找到了接口,也就能找到了对象,也就能调用接口支持的方法。一个COM组件对象可以提供很多接口,从另一个角度来说也就是很多接口使用同一个COM组件对象。如果每使用一个接口就创建一个COM组件对象,那该多浪费啊。
我们希望是:
而不是:
这样在使用同一个COM对象提供的服务的时候,可以只创建一个COM对象,而不是调用一次就创建一次。节省了系统资源。
   实现同一个COM对象在系统中只存在一份,首先要解决的问题就是:什么时候创建对象?什么时候销毁对象?正确答案:在需要的时候创建对象,在不需要的时候销毁对象。呵呵,只不过这答案讲跟不讲没有什么区别。COM技术中运用了“引用计数(reference count)”这一概念,如果对C++中的智能指针auto_ptr熟悉的话。COM里的“引用计数”和智能指针auto_ptr里的“引用计数”一样,都是用来标识当里的对象被使用的次数。当对象被引用一次就在其“引用计数器”上增加“1”,当“引用计数器”的值为“0”(这时意味着当该对象已没有被引用)时销毁对象。
   现在通过两个函数AddRef(),Release()正式揭开COM对象中的“引用计数”:
1,AddRef()
   在调用COM对象接口时,调用AddRef(),AddRef()在其接口使用的COM对象的“引用计数器”加“1”;
2,Release()
   在引用完COM对象接口之后,调用Release(),Release()的实现如下(伪代码):
a,"引用计数" - 1;
b,if("引用计数" == 0)
  {
     释放COM对象;
  }
 
   我们解决了什么时候创建COM对象?什么时候销毁COM对象?之后让我再看接口使用中的另外一个问题,在同一个对象中怎么从一个接口跳至另外一个接口。我们在创建一个COM对象时会返回一个且仅返回一个接口的指针。我们想要调用另外的接口该怎么办呢?
   这次的答案很明确,使用的每个接口都会有的一个方法QueryInterface(),根据传入的接口IDD(还记得吗?若不,请看上回),可以返回该IDD对应的指针,相应的也可以调用其方法了。
3,QueryInterface()
   根据传入的接口IDD,返回接口相应的指针;
 
   我们每一个接口都要有完成这个上面这三个功能的能力,即AddRef(),Release(),QueryInterface(),从面向对象的角度来讲,一个统一的抽象表示非“基类”莫可了。COM也采用的这种方案。即定义一个“基接口”,“基接口”分别实现AddRef(),Release(),QueryInterface()方法。这个接口被命名为“IUnknow”。COM规定所有的COM接口都必须从IUnkwon继承,继承IUnkwon的三个方法的申明,进而在接口所对应的COM对象中实现这三个方法。
 
 
  把上面的内容整理一下:
IUnkwon申明以下三个方法:
1,AddRef();
2,Release();
3,QueryInterface();
每个接口都必须继承IUnkwon,并实现上面的三个方法。
 
注:接口的继承,只继承接口的申明,并不是接口的实现。例如(伪代码):
public interface()
{
   void AddRef();
   void Release();
   void *QueryInterface();
}
该接口本身也没有实现部分,具休的实现部分要在实现接口的类中完成,例如(伪代码):
class IA:public interface
{
private:
  int m_value;
public:
IA();
~IA();
void AddRef(){m_value++;};
void Release(){m_value--; m_value == 0?Release(COM组件D):;}
.....
.....
}
 
 
 
 
 
 
 
 
 
 
Jerry_Chow
       7/1'07
 
阅读(934) | 评论(0) | 转发(0) |
0

上一篇:我的工作桌

下一篇:软件开发的环节

给主人留下些什么吧!~~