实现接口,从IUnknown开始

转载 2012年03月31日 09:21:16
实现接口,从IUnknown开始
有必要回想一下IUnknown派生的每一个接口。因为IUnknown包含了两个COM对象的基本特性——引用计数和接口查询。当你编写组件对象类时(coclass),还要写一个满足自己需要的IUnknown实现。以实现IUnknown接口的组件对象类为例——下面这个例子可能是你编写的最简单的一个组件对象类。我们将在一个叫做CUnknownImpl的C++类中实现IUnknown。下面是这个类的声明:
class CUnknownImpl : public IUnknown{public:    // 构造函数和析构器    CUnknownImpl();    virtual ~CUnknownImpl();    // IUnknown 方法    ULONG AddRef();    ULONG Release)();    HRESULT QueryInterface( REFIID riid, void** ppv );protected:    UINT m_uRefCount;  // 对象的引用计数};
构造器和析构器
构造器和析构器管理服务器的引用计数:
CUnknownImpl::CUnknownImpl(){    m_uRefCount = 0;    g_uDllRefCount++;}CUnknownImpl::~CUnknownImpl(){    g_uDllRefCount--;}
当创建新的COM对象时,构造器被调用,它增加服务器的引用计数以保持这个服务器驻留内存。同时它还将对象的引用计数初始化为零。当这个COM对象被摧毁时,它减少服务器的引用计数。
AddRef()和Release()这两个方法控制COM对象的生命期。AddRef()很简单:ULONG CUnknownImpl::AddRef(){    return ++m_uRefCount;}AddRef()只增加对象的引用计数并返回更新的计数。Release()更简单:ULONG CUnknownImpl::Release(){ULONG uRet = --m_uRefCount;    if ( 0 == m_uRefCount )  // 是否释放了最后的引用?        delete this;    return uRet;}
除了减少对象的引用计数外,如果没有另外的明确引用,Release()将摧毁对象。Release()也返回更新的引用计数。注意Release()的实现假设COM对象在堆中创建。如果你在全局粘上创建某个对象,当对象试图删除自己时就会出问题。
现在应该明白了为什么在客户端应用程序中正确调用AddRef()和 Release()是如此重要!如果在这了做得不对,你使用的对象会被很快摧毁,这样的话在整个服务器中内存会很快溢出导致应用程序下次存取服务器代码时崩溃。
如果你编写多线程应用,可能会想到使用++&替代InterlockedIncrement()和InterlockedDecrement()的线程安全问题。++&——用于单线程服务器很保险,因为即使客户端应用是多线程的并从不同的线程中进行方法调用,COM库都会按顺序进行服务器的方法调用。也就是说,一旦一个方法调用开始,所有其它试图调用方法的线程都将阻塞,直到第一个方法返回。COM库本身确保服务器一次不会被一个以上的线程闯入。

COM组件中的 IUnknown接口(1)

COM组件的一个主要优势是:便于升级。要实现这个优势需要满足两个条件: 1>为了更好的突出DLL的优势,还需要信息隐藏,即封装性。 2>运行时客户程序可动态加载和卸载,采用DLL技术可以实现。 ...
  • CNHK1225
  • CNHK1225
  • 2015年05月20日 11:23
  • 545

通过ATL实现IUnknown接口

每个COM组件需要实现这三个功能 1. 实现IUnknown接口 (通过 CComObjectRootEx 实现) 2. 实现一个类工厂,支持组件的创建 (通过 CComCoClass 实现) ...
  • wishfly
  • wishfly
  • 2013年09月27日 10:10
  • 820

ATL中IUnknown接口的实现(一)

ATL和MFC都能作为开发COM的工具,而ATL是一个Template Library,MFC却是一个Framework,作为Template Library,其优势在于其只是提供给程序员形式各异,可...
  • Andeewu
  • Andeewu
  • 2013年04月10日 10:05
  • 859

COM---多线程

调整 将函数调用的参数从一个进程的地址空间传到另一个进程的地址空间。COM直接使用了Win32线程,但仍有细微差异。Win32线程:用户界面线程、工作线程 COM线程:套间线程(类似于用户界面线程...
  • u012319493
  • u012319493
  • 2017年02月19日 23:59
  • 171

COM编程之IUnknown接口

COM组件其实是一种特殊的类,遵循一个统一的标准,使到各个软件都可以通过某种方法访问这个类的函数和方法,也就可以做到组件通用. com就是统一的标准--通过接口来调用com组件.接口是你的com组件能...
  • xdrt81y
  • xdrt81y
  • 2013年09月13日 16:36
  • 1633

COM学习笔记(三)IUnknown接口

一: 接口定义     任何一个接口都是继承于IUnknown接口。   客户同组件的交互都是通过一个接口完成的。在客户查询组件的其他接口时,也是通过接口完成的。这个接口就是Iunkown...
  • Andeewu
  • Andeewu
  • 2013年03月28日 22:06
  • 760

COM组件编程—IUnknown的三个接口函数

对于COM组件,正确处理IUnknown的三个接口函数非常重要。 对于QueryInterface,一个参考处理如下: HRESULT __stdcall CA::QueryInterface...
  • u012905728
  • u012905728
  • 2015年02月11日 10:13
  • 820

COM组件开发(一)—— 对象与接口

一.前言        在COM规范中,最基本的两个要素就是对象与接口,因为COM就是由这两者来共同实现的。COM对象在组件中是被封装起来的,客户代码只能通过接口来访问COM对象并享受其,由于客户与C...
  • q5806622
  • q5806622
  • 2015年01月19日 23:08
  • 3542

IDispatch接口的作用

网上说法1: IDispatch 接口是COM中比较常用的接口。 如果某个COM对象继承了IDispatch接口,那么这个COM对象所有的方法和属性都可以以它们的名称为参数,通过调用IDispatc...
  • hexiaomin_1984
  • hexiaomin_1984
  • 2014年02月24日 15:02
  • 476

Java对多线程的支持(一) - Thread类、Runnable接口、Daemon线程、线程同步

Java是第一个在语言级提供了对多线程程序设计支持的语言。语言级支持是啥意思呢,就是抛开操作系统,只使用Java内置的语句就能实现多线程。一般来讲,多线程会依赖操作系统,我们要高用与系统相关的API才...
  • twlkyao
  • twlkyao
  • 2013年10月15日 20:27
  • 1207
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:实现接口,从IUnknown开始
举报原因:
原因补充:

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