Inside COM 学习笔记三

原创 2007年10月09日 13:59:00

虽然这些东西在后面的发展中可能被隐藏掉或者取消掉,但是知道其原理对技术的发展会有更深刻的理解。

**************************学习笔记三************************
QueryInterface的实现规则
1.QueryInterface返回的总是同一个IUnknown指针;
2.若客户曾经获取过某个接口,那么它将总能获取次接口;
3.客户可再次获取已经拥有的接口;
4.客户可以返回到起始接口;
5.若能够从某个接口获取特定接口,那么可以从任意接口都将可以获取此接口。

新版本组件的处理
对QueryInterface而言,一个IID 就是一个接口。当QueryInterface接收到对老IID的查询时,它将返回老的接口。
接口的标识符同版本是绑在一块的。

何时需要一个新版本
为使COM处理多个版本的机制能够其作用,程序员在给某个已有接口的新版本制定新的ID时应非常严格。当改变了下列条件中的任何一个时,就应给新接口制定新的IID:
1.接口中函数的数目;
2.接口中函数的顺序;
3.某个函数的参数;
4.某个函数参数的顺序;
5.某个函数参数的类型;
6.函数可能的返回值;
7.函数返回值的类型;
8.函数参数的含义;
9.接口中函数的含义。

不同版本接口的命名
COM关于新版本名称的约定是在老名称的后面加上一个数字。

组件生命期控制

COM中客户对组件知道的仅仅是其接口,因此客户也就无法直接控制整个组件的生命期,不过可以通过控制单个接口生命期来间接控制组件生命期的方法。
一般来说,不同的客户可以使用同一组件中不同的接口,所以决定何时使用完一个组件并不是一件简单的事。而我们可以通知组件何时需要使用的它的某个接口,何时使用完他的次接口。对组件的四方就可以由组件在客户使用完其各个接口之后自己完成。
AddRef就是提供客户给组件发指示使用某接口的方法;
Release就是提供客户给组件发指示使用完某接口的方法;
AddRef和Release可以实现让组件自己来管理其生命周期,以及客户如何只关注接口的使用。

引用计数简介
AddRef和Release实现的是一种名为引用技术的内存管理技术。
COM组件维护一个称作是引用计数的数值。当客户从组件取得一个接口时,此引用计数值将增1.当客户使用完某个接口后,组件的引用计数值减1。当引用计数值为0时,组件自己将自己从内存中删除。

为了正确使用引用计数了解三条简单规则
1.在返回之前调用AddRef。对于那些返回接口指针的函数在返回之前调用AddRef,这样客户得到接口后无需调用AddRef;
2.使用完接口之后调用Release;
3.在赋值之后调用AddRef。

第二条规则代码例子

//Create a new component
IUnknown * pIUnknown = CreateInstance();

IX 
*pIX = null;
HRESULT hr 
= pIUnknown->QueryInterface(IID_IX,(void**)&pIX);
if (SUCCEEDED(hr))
...{
 pIX
->Fx1();
 pIX
->Release();
}

pIUnknown
->Release();

 

第三条规则例子

IUnknown *PIUnknown = CreateInstance();
IX 
*pIX = null;
HRESULT hr 
= pIUnknown->QueryInterface(IID_IX,(void**)&pIX);
pIUnknown
->Release();

if(SUCCEEDED(hr))
...{
 pIX
->Fx();
 IX 
*pIX2 = pIX;
 pIX2
->AddRef();
 pIX2
->Fx();
 pIX2
->Release();
 pIX
->Release();
}


但是不是每次复制指针都必须调用AddRef函数的。在这个例子中pIX2和pIX的生命周期是一样的。不一定要使用AddRef和Release。组件优化后就使用时不一定遵循这三个规则了,但其本质是没有变的。只是一些细节被优化和隐藏了。

引用计数方案

在组件维护引用计数时,采用的方案是对每个接口维护一个引用计数。

AddRef和Release的简单实现

ULONG __stdcall AddRef()
...{
 
return ++ m_cRef;
}


ULONG __stdcall Release()
...{
 
if (--m_cRef == 0)
 
...{
  delete 
this;
  
return 0;
 }

}

 

SEM实战教程(三)

-
  • 1970年01月01日 08:00

[Inside COM][COM技术内幕]

  • 2009年05月27日 17:36
  • 9.21MB
  • 下载

Inside Com 源代码

  • 2012年03月09日 18:05
  • 1.5MB
  • 下载

Inside COM

  • 2014年07月28日 11:01
  • 9.33MB
  • 下载

Inside.COM的随书源代码

  • 2008年03月17日 11:38
  • 1.71MB
  • 下载

Inside COM学习笔记(五)

   关于HRESULT、GUID、注册表及其他细节COM使用HRESULT来向用户报告各种情况。HRESULT并不完全是指向某个结果的句柄。HRESULT实际上是一个可分成三个位域的32位值。系统生...
  • waterathena
  • waterathena
  • 2007-10-09 14:03:00
  • 705

Inside Com学习笔记(一)

以前总是接触C/C++的一些皮毛的东西,或者说是基础的东西。一直都没有完成从中级程序员向高级程序员的过渡。现在越来越发现新的知识需求量很大。准备好好研究下COM、STL、Templete。好好学习天天...
  • waterathena
  • waterathena
  • 2007-10-09 13:50:00
  • 635

Inside COM学习笔记(四)

在前面的例子当中客户(main函数)和组件不但是静态链接在一切的,而且它们在同一个文件中。在完全实现了IUnknown之后,组件和客户之间变成非常松散的关系。那么这里讨论如何将组件放入到动态链接库(D...
  • waterathena
  • waterathena
  • 2007-10-09 14:02:00
  • 564

Inside COM学习笔记(二)

接口查询客户同组件的交互都是通过一个接口完成的。在客户查询组件的其他接口时,也是通过接口完成的。这个接口就是IUnknown。IUnknow接口的定义包含在Win32 SDK中的UNKNWN.H头文件...
  • waterathena
  • waterathena
  • 2007-10-09 13:56:00
  • 705

Inside COM souce code

  • 2012年02月25日 12:21
  • 2.16MB
  • 下载
收藏助手
不良信息举报
您举报文章:Inside COM 学习笔记三
举报原因:
原因补充:

(最多只允许输入30个字)