博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(转)COM组件里的AddRef()
阅读量:5260 次
发布时间:2019-06-14

本文共 1397 字,大约阅读时间需要 4 分钟。

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()。

转载于:https://www.cnblogs.com/wonderKK/archive/2011/11/07/2240281.html

你可能感兴趣的文章
UVa 12545 比特变换器
查看>>
数组分割问题求两个子数组的和差值的小
查看>>
10个著名的思想实验1
查看>>
composer 报 zlib_decode(): data error
查看>>
03_java基础(一)之计算机应用知识普及
查看>>
C#微信公众号开发-高级接口-之网页授权oauth2.0获取用户基本信息(二)
查看>>
C++中memset()函数的作用
查看>>
微信展会报名签到入场系统asp源码写的asp微信会展报名系统程序
查看>>
JavaScript日志
查看>>
SSD硬盘的4K对齐
查看>>
OpenFire源码学习之三十一:使用Tsung测试openfire(上)
查看>>
红帽7 vsftpd服务
查看>>
mysql update select 从查询结果中更新数据
查看>>
牛客小白赛4J——强迫症
查看>>
Kohana::ORM学习
查看>>
On the Criteria To Be Used in Decomposing Systems into Modules
查看>>
Java表格模型事件示例
查看>>
0034 Java学习笔记-反射-初步2-操作对象
查看>>
沙盒、文件以及文件夹的操作
查看>>
Eclipse中CVS的使用
查看>>