有关IUnKnown的Info .

一:

当 COM 认为不再使用某个对象时,COM 本身不会自动尝试将该对象从内存中移除。相反,该对象的程序员必须移除未使用的对象。程序员根据引用数确定是否可以将对象移除。

COM 使用 IUnknown 方法、AddRef 和 Release 管理对象上的接口的引用数。调用这些方法的一般规则是:

每当客户端收到一个接口指针时,都必须在该接口上调用AddRef

每当客户端已完成对接口指针的使用时,它必须调用Release

在简单实现中,每个 AddRef 调用都会增加同时每个 Release 调用都会减少对象中的计数器变量。当计数返回到零时,此接口不再有任何用户并可以从内存中移除其本身。

还可以实现引用计数以便对该对象(不是对单个接口)的每个引用都进行计数。在此情况下,每个AddRefRelease 调用都委托给对象上的中心实现,并且当对象的引用数达到零时,由Release 释放整个对象。

注意   当使用new 运算符构造 CComObject 派生对象时,引用数为 0。因此,必须在成功创建 CComObject 派生对象后调用 AddRef

QueryInterface

尽管存在对象可以用来静态地(在对象被实例化之前)表示它所提供的功能的机制,但基本的 COM 机制将使用称为 QueryInterface 的IUnknown 方法。

每个接口都从 IUnknown 中派生,因此每个接口都有一个 QueryInterface的实现。不论什么实现,该方法都使用接口(调用方需要一个指向该接口的指针)的 IID 查询对象。如果对象支持该接口,则 QueryInterface 检索指向该接口的指针,而且还调用AddRef。否则,它返回 E_NOINTERFACE 错误代码。

请注意,您必须永远遵守引用计数规则。如果调用接口指针上的Release 将引用数减小到零,则不应再使用该指针。有时,您可能需要获取对对象的弱引用(即您可能希望获取指向该对象接口之一的指针但不增加引用数),但不可以通过先调用QueryInterface 然后调用 Release 达到此目的。以这种方式获取的指针无效并且不应使用。当定义 _ATL_DEBUG_INTERFACES 时,这会变得更加明显,因此定义该宏是查找引用计数错误的有用方法。

封送处理

COM 封送处理技术允许在一个进程中使用由另一个进程中的对象公开的接口。在封送处理中,COM 提供(或由接口实现者提供)具有以下功能的代码:将方法的参数压缩成可以在进程之间移动的格式,并在另一端将这些参数解压缩,可以在进程之间移动还包括可以通过线路到达其他计算机上运行的进程。同样,COM 必须对该调用的返回执行这些相同步骤。

注意   当对象提供的接口在与该对象相同的进程中使用时,通常不必进行封送处理。但是,线程之间可能需要进行封送处理。

聚合

有时,对象的实现者希望利用另一个预生成对象所提供的服务。而且,它希望第二个对象显示为第一个对象的固有组成部分。COM 通过包容和聚合来达到这两个目标。

聚合意味着包含(外部)对象创建被包含(内部)对象作为其创建过程的一部分,以及内部对象的接口由外部对象公开。对象允许本身为可聚合的或不可聚合的。如果对象为可聚合的,则它必须遵循某些聚合规则以正确地工作。

主要地,所有被包含对象上的 IUnknown 方法调用必须委托给包含对象。

二:

IUnknown接口两个重要特性:

1.生存期控制

    客户程序只能通过接口与COM对象进行通信,虽然客户程序可以不管对象内部的实现细节,但它要控制存在与否.

    如果客户对对象的操作已完成,以后也不再需要该对象,则必须及时把对象释放掉。

    IUnknown引入了引用计数(reference counting)的方法,有效控制对象生存周期。

2.接口查询

    在初始时刻,客户程序不太可能得到该对象的所有接口指针,它只会拥有一个接口指针。如果客户程序需要其他的指针,那么它如何通过这个接口指针获得另一个接口指针呢?IUnkown使用了"接口查询"(QueryInterface)的方法来完成接口之间的跳转.

IDL描述

interface IUnknown

{

    HRESULT    QueryInterface([in] REFIID iid,[out] void **ppv);

    ULONG       AddRef(void);

    ULONG       Release(void);

}

C++描述:

class IUnknow

{

public:

      virtual  HRESULT    _stdcall Queryface(const IID& iid,void **ppv) = 0;

      virtual  ULONG       _stdcall AddRef() = 0;

      virtual  ULONG       _stdcall  Release() = 0;

};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值