`

引用计数和AddRef、Release

 
阅读更多

AddRef和Release实现的是一种名为引用计数的内存管理技术,这种技术是使组件能够自己将自己删除的最简单同时也是效率最高的方法。COM组件将维护一个称作是引用计数的数值。当客户虫组件取得一个接口时,此数值增1,当客户使用完某个接口后,此数值将减1。当此数值为0时,组件即可将自己从内存中删除。

为正确的使用引用计数,需要了解一下三条规则:
(1)在返回之前调用AddRef。对于哪些返回接口指针的函数,包括QueryInterface和CreateInstance,在返回之前用相应的指针调用AddRef。
(2)使用完接口之后调用此接口的Release函数。
(3)在赋值之后调用AddRef。如在将一个接口赋给另外一个接口指针时调用AddRef。
生命期嵌套在引用同一接口的指针的生命期内的指针可以不进行引用计数。在函数中,无需对存在于局部变量的接口指针进行引用计数。因为局部变量的生命期同函数的生命期是一样的,因此也将包含在调用者的生命期内。但当从某个全局变量或向某个全局变量复制一个指针时,则需要对此指针进行引用计数,因为全局变量可以从任意函数中的任意地方被释放。
一般而言,客户必须为每一个接口维护一个单独的引用计数值。
总结引用计数的几条具体规则如下:
(1)输出参数规则。任何在输出参数中(如QueryInterface的void** ppv)或作为返回值返回一个新的接口指针的函数必须对此接口指针调用AddRef。即在返回之前调用AddRef。
(2)输出参数规则。在输入参数(C++的按值传递的参数或常量)传入函数的接口指针,无需调用AddRef和Release。因为函数的生命期嵌套在调用者的生命期内。
(3)输入-输出参数规则,即在函数体中可以使用输入-输出参数的值,然后可以对这些制进行修改并将其返回给调用者,对于具有这种功能的参数传进来的接口指针,必须在给它赋另外一个接口指针值之前调用其Release,并在函数返回之前,对输入参数中所保存的接口指针调用AddRef。
(4)局部变量规则。对于局部复制的接口指针,由于它们只在函数的生命期内才存在,无需调用AddRef和Release。
(5)全局变量规则。对于保存在全局变量中的接口指针,在将其传递给另外一个函数之前,必须调用其AddRef。对于保存在成员变量中的接口指针,也应按此中方式进行处理。因为类中的任何成员函数都可以改变此中接口指针的状态。
(6)不能确定时的规则。对于任何不能确定的情形,都应调用AddRef和Release。
在决定要对引用计数进行优化时,应给哪些没有进行引用计数的指针加上相应的注释,否则,其他程序员在修改代码时,将可能会增大接口指针的生命期,从而使引用计数的优化遭到破坏
分享到:
评论

相关推荐

    VC++ COM组件开发相关实例

    4.2 引用计数和AddRef/Release函数 引用计数 - 就是一个整数,作用是 表示接口的使用次数 AddRef - 增加引用计数 +1 Release - 减少引用计数 -1, 如果 当引用计数为0,接口被删除 4.3 使用 4.3.1 创建接口 ...

    com自学视频教程

    2、引用计数的原理 3、AddRef与Release的实现与使用 4、引用计数的优化 IDispatch接口与Variant类型 内容提要: 1、IDispatch的简介与作用 2、常用的COM数据类型 3、COM数据类型的转换 4、VARIANT类型的派生...

    AddRef.doc

    AddRef.doc

    易语言进度下载

    易语言进度下载源码,进度下载,QueryInterface,AddRef,Release,OnStartBinding,GetPriority,OnLowResource,OnProgress,OnStopBinding,GetBindInfo,OnDataAvailable,OnObjectAvailable,URLDownloadToFile

    COM技术内幕——微软组件对象模型--随书源代码

    4.2.2 AddRef和Release的实现 53 4.3 何时进行引用计数 60 4.3.1 引用计数的优化 60 4.3.2 引用计数规则 63 4.4 本章小结 65 第5章 动态链接 66 5.1 组件的创建 66 5.1.1 从DLL中输出函数 67 5.1.2 DLL的...

    挂接IE事件之IConnectionPoint

    NewWindow3,ToCLSID,QueryInterface,AddRef,Release,GetTypeInfoCount,GetTypeInfo,GetIDsOfNames,Invoke,取回参数1数据,写入参数数据,取变体型数据区指针,取变体型数据_整数型,取变体型数据_长整数型,取变体型指针,...

    易语言设置Win7进程音量

    易语言设置Win7进程音量源码,设置Win7进程音量,SetProcessVolume,FAILED,取变量数据地址_字节集,QueryInterface,AddRef,Release,EnumAudioEndpoints,GetDefaultAudioEndpoint,GetDevice,...

    易语言控制托盘图标

    易语言控制托盘图标源码,控制托盘图标,WriteInt,L,QueryInterface,AddRef,Release,ITrayNotify_RegisterCallback,ITrayNotify_SetPreference,ITrayNotify_EnableAutoTray,ITrayNotifyWin8_RegisterCallback,...

    易语言VISTA系统音量

    易语言VISTA系统音量源码,VISTA系统音量,GET_APPCOMMAND_LPARAM,HIWORD,LOWORD,A2W,GetVolumnVista,VolumnUp,VolumnDown,Mute,IsMute,SetVolumnVista,QueryInterface,AddRef,Release,EnumAudioEndpoints,...

    易语言对象枚举

    易语言对象枚举源码,对象枚举,枚举对象,EnumITypeInfo,EnumObj,CreateInstance,CallInstanceMethod,ToCLSID,A2W,W2A,QueryInterface,AddRef,Release,GetTypeInfoCount,GetTypeInfo,GetIDsOfNames,Invoke,GetTypeAttr...

    Visual C++实践与提高-COM和COM+篇『PDF』

    3.1.3.1 生存期控制:AddRef和Release 3.1.3.2 接口查询:QueryInterface 3.1.4 全球唯一标识符GUID 3.1.5 COM接口定义 3.1.6 接口描述语言IDL 3.2 COM应用模型 3.2.1 客户/服务器模型 3.2.2 进程内组件 3.2.3 进程...

    深入COM服务器.doc

    • AddRef() 和 Release() • QueryInterface() • 深 入CoCreateInstance()——探究CoCreateInstance()的调用机理 • COM 服务器的注册——描述完成服务器注册所需要的注册表入口 • 创 建COM对象——类工厂——...

    易语言网页事件挂接

    易语言网页事件挂接源码,网页事件挂接,E_event,语言,超时,加入脚本,计算表达式,执行,运行,取错误,清除,写Html,加入对象,加入Dom,加入E函数,加入E类,QueryInterface,AddRef,Release,GetTypeInfoCount,GetTypeInfo,...

    易语言Shell外壳运行

    易语言Shell外壳运行源码,Shell外壳运行,枚举快捷方式菜单,ParseDisplayName,EnumObjects,BindToObject,QueryInterface,AddRef,Release,bstr_t,A2W,W2A,CallObject,调用子程序_,指针到整数,取整数型指针,StringTo...

    易语言-易语言利用WebKit打造你的HTML5浏览器

    (All).AddRef() '给这个函数所属的类增加一次引用计数 (All).Release() '给这个函数所属的类释放一次引用计数 (All).HasOneRef() '判断当前这个类是不是第一次被引用 (All).Wrap() '实际上《Hello WebKit》框架...

    TSSource_srcC++

    pNew->AddRef(); // The caller must release everything in the list. FilterList.AddTail(pNew); } // Get the first upstream or downstream filter HRESULT Demux::GetNextFilter( IBaseFilter *pFilter, //...

    ReDo UnDo的好例子

    pItem->AddRef(); } void CMyObjCollection::Remove(CMyObject* pItem) { for (vector*>::iterator it = m_vecMyObjects.begin(); it != m_vecMyObjects.end(); it++) { if (*it == pItem) { m_...

    pdfium.dll_windows-x86

    Google开源PDFium项目采用福昕PDF技术作为其开源PDF渲染引擎的Dll

    JS动态给对象添加事件的简单方法

    下面小编就为大家带来一篇JS动态给对象添加事件的简单方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    PDFiumSDK.7z

    用 VS2017,从 PDFium 源码,编译的 X86、X64 位 pdfium.dll。 MT 方式编译。无需VS运行库。 包含 PDFium 开发所需的头文件、库文件、Dll 文件(X86、X64)。

Global site tag (gtag.js) - Google Analytics