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;
 }

}

 

Inside COM读书笔记------接口

1.接口的作用 组件可以充应用程序中删除并可用另外一个组件代替,只要新的组件支持同样的接口。单个组件并不能起决定性作用,相反,用以连接组件的接口对应用程序亲戚到决定性作用。使用组件来构成应用...
  • wangqiulin123456
  • wangqiulin123456
  • 2013年05月09日 19:01
  • 1735

Inside COM读书笔记-----多线程

1.      COM线程模型 COM并没有定义新的线程和进程模型,而是直接使用Win32线程。 1.1Win32线程          典型的Win32线程具有两种不同...
  • wangqiulin123456
  • wangqiulin123456
  • 2013年05月22日 21:24
  • 2245

重读COM技术内幕(inside com)有感

重读COM技术内幕(inside com)有感面向对象设计哲学在复杂领域并不能很好地解决问题。参考(http://www.richardlord.net/blog/what-is-an-entity-...
  • cheungmine
  • cheungmine
  • 2016年06月07日 12:59
  • 6338

Inside COM读书笔记-----包容和聚合

1.      包容和聚合 包容和聚合实际上是使一个组件使用另一个组件的一种技术。 包容简介          外部组件包含指向内部组件接口的指针,外部组件只是内部组件的一个客户。外部组件也可以...
  • wangqiulin123456
  • wangqiulin123456
  • 2013年05月22日 20:57
  • 2608

Inside COM读书笔记------动态链接库

1.      组件的创建 在客户获取某个组件接口指针之前,必须先将相应的DLL装载到起进程空间中并创建此组件。 从DLL中输出函数 先将需要输出的函数用extern “C”进行...
  • wangqiulin123456
  • wangqiulin123456
  • 2013年05月13日 20:56
  • 2358

Inside COM读书笔记-----类厂

1.CoCreateInstance      通过传人参数CLSID创建相应组件的一个实例,并返回此组件实例的某个接口。      CoCreateInstance的声明 ...
  • wangqiulin123456
  • wangqiulin123456
  • 2013年05月14日 18:38
  • 2475

Inside COM读书笔记------引用计数

1.      生命期控制 当使用完一个接口而仍要使用另外一个接口时,是不能将此组件释放掉的。很难知道两个指针是否指向同一个对象。IUnknown的另外两个函数AddRef和Release来...
  • wangqiulin123456
  • wangqiulin123456
  • 2013年05月13日 20:53
  • 1988

Inside COM读书笔记-----ExE中的服务器

1.      不同的进程 每一个EXE文件都将在不同的进程中运行,而每一个进程都有其自己的进程空间。一个进程空间中的逻辑地址0X0000ABBA所对应的物理地址将不同于另外一个进程中同一逻辑地址所...
  • wangqiulin123456
  • wangqiulin123456
  • 2013年05月22日 21:09
  • 2382

COM组件开发(三)——类厂对象

COM类厂对象的实现         COM客户程序要使用COM对象是通过COM库创建而来的,而实际上COM库是调用COM对象的类厂来创建的。COM类厂对象也是一个COM对象,所以它也从IUnkno...
  • q5806622
  • q5806622
  • 2015年02月04日 19:32
  • 2414

Inside COM读书笔记-----调度接口与自动化

1.  一种新的通信方式 IDispatch为客户和组件提供了另外一种通信方式,有了IDispatch后,COM组件可以通过一个标准的接口提供它所支持的服务,而无需提供多个特定与服务的接口。...
  • wangqiulin123456
  • wangqiulin123456
  • 2013年05月22日 21:15
  • 3784
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Inside COM 学习笔记三
举报原因:
原因补充:

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