(转)COM组件里的AddRef()
D3D是 COM组件,它在服务进程中运行,而不在当前的客户进程中。在DX组件运行过程中,要创建一系列接口对象,如CreateDevice()返回接口指针,这些接口及其占用内存什么时候释放,要通过“引用计数”的技术来解决。AddRef()给这个接口指针的计数加1,而Release()会将之减1。一旦减到0,表示没有客户使用了,相关的接口就释放了。由此可知,每次调用Rlease()后,并不一定会释放内存,而是当引用计数归0时释放内存。
这样,对接口指针的使用,就像维护堆栈的平衡一样,要仔细,而且按照某种约定规则使用。
但平时D3D编程中,怎么不用AddRef()呢?这是由于一个接口指针,如ID3DDevice,或VertexBuf指针,都是 D3DXCreate出来的,在Create时候,在内部已经事先AddRef()了,你就不需要再做这工作了。只要你在不用时,调用 p指针 ->Relase()就释放了。一般编程,特别是小型示例程序,都是初始化时建立一次,关闭时释放,都遵守了这种约定,所以不存在这种问题。
但在CreateMeshContainer()函数中,以多种方式使用了指针,在局部指针变量中来回传递,所以问题复杂化了。在COM编程中约定,任何时候地接口指针赋值(复制),都要AddRef(),在指针变量结束生命期前,再Release(). 但许多程序员都不是严格这么做。因为在局部变量用完就废了,先AddRef()增加计数再Release()减少,和直接使用最后是等效的。几乎是多此一举。这与编程习惯有关系。一旦引用计数不对,如果没有统一的习惯,不好排查。在CreateMeshContainer()中,对接口指针的使用有三种方式,例举如下:
方式一:不使用AddRef()。和普通指针一样,临时变量是左值,接口指针是右值,直接赋值使用。如:
pMesh = pMeshData->pMesh;
这是由于pMesh是局部变量,它只是临时引用一下,没必要为它先AddRef(),后Release()。
方式二:隐式的使用AddRef()。由于用到了一些内部有AddRef()动作的函数,就要按照COM约定,在子程序结束前Release()
pMesh->GetDevice(&pd3dDevice);//此处d3d设备引用计数已经加1
....
SAFE_RELEASE(pd3dDevice);//--此处将引用计数减1,并不是真的释放d3d设备
在本例中,pd3dDevice在GetDevice()中已经Addref()过了,所以,在退出CreateMeshContainer()前,必须pd3dDevice->Release()
方式三:显式的使用AddRef()。如果一个指针值,不是由D3DXCreate出来的,而是通过赋值方式复制给一个全局变量或长期变量的。所以,可以通过AddRef()的方式来延迟该对象的释放。因为,如果不AddRef(),极有可能在函数返回该对象就可能释放了。它就像一个加油站,使得传入对象的寿命延长至自己控制范围内。用了AddRef(),就要在相关的Destroy中添加Release()。
(转)COM组件里的AddRef()的更多相关文章
- JavaScript实现点击按钮弹出输入框,点确定后添加li组件到ul组件里
JavaScript实现点击按钮弹出输入框,点确定后添加li组件到ul组件里 <!doctype html> <html manifest="lab4.manifest&q ...
- 40.VUE学习之--组件之间的数据传参父组件向子组件里传参,props的使用实例操作
父组件向子组件里传参,props的使用实例 <!DOCTYPE html> <html> <head> <meta charset="utf-8&q ...
- webpack单独构建scss文件与.vue组件里构建scss的一个坑
在入口main.js里构建scss是通过引入模块的方式 import './assets/_reset.scss'; import './assets/_flex.scss'; import './a ...
- Django forms组件里的ChoiceField、ModelChoiceField和ModelMutipleChoiceField的区别
阅读简要 首先我们要明白Django forms组件里的ChoiceField.ModelChoiceField和ModelMutipleChoiceField是继承关系 ChoiceField 1. ...
- 关于MUI v0.18.0版本 Table组件里的复选框不能选的解决方案
前段时间在用MUI的时候,Table组件出现复选框不能选的bug(描述: 点击复选框,点击事件会触发,复选框勾选状态无变化). 解决方法: 用CheckBox组件代替Table组件自带的复选框. 解决 ...
- vue使用props动态传值给子组件里的函数用,每次更新,呼叫函数
父组件 <template> <div id="app"> <div>详情内容</div> <button v-on:clic ...
- vue组件里不用的css还在搜索过滤来删除?试一下vue-clearcss吧!
这篇文章其实是推广介绍我个人的npm工具库,但你不会后悔点进来的(应该吧...)vue-clearcss 为什么要用它? 一个vue文件在长期迭代中css会越来越冗余,它不像html和js那么好删除, ...
- vue组件里定时器销毁问题
我在a页面写一个定时,让他每秒钟打印一个1,然后跳转到b页面,此时可以看到,定时器依然在执行.这样是非常消耗性能的.如下图所示: 解决方法1: 首先我在data函数里面进行定义定时器名称: data( ...
- vue 简单实现父组件向子组件传值,简单来说就是子组件肆意妄为的调用父组件里后台返回的值
首先在于父子组件传值的方法很多,本人在这里只是简单描述一下一个组件里面引用了子组件,那么子组件如何才能获取父组件中后台返回的值呢? 首先调用组件相信大家都应该明白了(不明白的自己撸撸文档), < ...
随机推荐
- spring.net object 配制节点记录
<object id="Login" name="LoginService" type="SoftSFramework.BaseInfoServ ...
- JSP之->初识JSP
JSP 引用百度百科的介绍: JSP(Java Server Pages)是由Sun Microsystems公司倡导.许多公司参与一起建立的一种动态网页技术标准.JSP技术有点类似ASP技术,它是在 ...
- Ant_的最完整build.xml解释
Ant的概念 Make命令是一个项目管理工具,而Ant所实现功能与此类似.像make,gnumake和nmake这些编译工具都有一定的缺陷,但是Ant却克服了这些工具的缺陷.最初Ant开发者在开发跨平 ...
- STM32F之IAR6.5 J-Link程序下载错误
错误01:Keil环境下使用J-Link SW模式下载程序,而IAR6.5则出现如图1-1的错误.
- 超简单的js数字验证
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or ...
- 7月07日——[HouseStark] 团队简介
团队名称 HouseStark 团队口号 winter's coming,fire's on! full of passion,we are young! pick the code, with th ...
- father of the archangel of death"?
e wields an axe, a sword and a machine gun and his battlefield pranks have become as legendary as hi ...
- sql转db,后台坑货
打开 创建一个db文件然后点击文件--新建---Sqlite 导入空db成功后点击左侧栏 点击表 点击右上角+号把sql文件的语句复制粘贴到 然后点击运行,运行完成后保存ok
- Hadoop中如何查看文件的block size
因为对控制文件的分片数目,进而控制文件的map个数非常感兴趣,因此有查找如下资料的需求.下面来看看我总结的吧:) 当向HDFS上写文件时,可以通过设置dfs.blocksize配置项来设置文件的blo ...
- #include <vector>用法之我见
vector是一种顺序容器,事实上和数组差不多,但它比数组更优越.一般来说数组不能动态拓展,(何为动态拓展,即是说如果你知道你要存的数据的个数,你定义的存储数据的数组大小也就决定了,但是若你事先不知道 ...