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()的更多相关文章

  1. JavaScript实现点击按钮弹出输入框,点确定后添加li组件到ul组件里

    JavaScript实现点击按钮弹出输入框,点确定后添加li组件到ul组件里 <!doctype html> <html manifest="lab4.manifest&q ...

  2. 40.VUE学习之--组件之间的数据传参父组件向子组件里传参,props的使用实例操作

    父组件向子组件里传参,props的使用实例 <!DOCTYPE html> <html> <head> <meta charset="utf-8&q ...

  3. webpack单独构建scss文件与.vue组件里构建scss的一个坑

    在入口main.js里构建scss是通过引入模块的方式 import './assets/_reset.scss'; import './assets/_flex.scss'; import './a ...

  4. Django forms组件里的ChoiceField、ModelChoiceField和ModelMutipleChoiceField的区别

    阅读简要 首先我们要明白Django forms组件里的ChoiceField.ModelChoiceField和ModelMutipleChoiceField是继承关系 ChoiceField 1. ...

  5. 关于MUI v0.18.0版本 Table组件里的复选框不能选的解决方案

    前段时间在用MUI的时候,Table组件出现复选框不能选的bug(描述: 点击复选框,点击事件会触发,复选框勾选状态无变化). 解决方法: 用CheckBox组件代替Table组件自带的复选框. 解决 ...

  6. vue使用props动态传值给子组件里的函数用,每次更新,呼叫函数

    父组件 <template> <div id="app"> <div>详情内容</div> <button v-on:clic ...

  7. vue组件里不用的css还在搜索过滤来删除?试一下vue-clearcss吧!

    这篇文章其实是推广介绍我个人的npm工具库,但你不会后悔点进来的(应该吧...)vue-clearcss 为什么要用它? 一个vue文件在长期迭代中css会越来越冗余,它不像html和js那么好删除, ...

  8. vue组件里定时器销毁问题

    我在a页面写一个定时,让他每秒钟打印一个1,然后跳转到b页面,此时可以看到,定时器依然在执行.这样是非常消耗性能的.如下图所示: 解决方法1: 首先我在data函数里面进行定义定时器名称: data( ...

  9. vue 简单实现父组件向子组件传值,简单来说就是子组件肆意妄为的调用父组件里后台返回的值

    首先在于父子组件传值的方法很多,本人在这里只是简单描述一下一个组件里面引用了子组件,那么子组件如何才能获取父组件中后台返回的值呢? 首先调用组件相信大家都应该明白了(不明白的自己撸撸文档), < ...

随机推荐

  1. serialize和unserialize函数

    序列化是将变量转换为可保存或传输的字符串的过程:反序列化就是在适当的时候把这个字符串再转化成原来的变量使用.这两个过程结合起来,可以轻松地存储和传输数据,使程序更具维护性.1. serialize和u ...

  2. 解决 主界面mainactivity 中fragment弹框把下面tab选项卡 顶上去的方案

     android:windowSoftInputMode="adjustPan"            android:configChanges="screenSize ...

  3. ubuntu 13.04 telnet 详细配置

    1. sudo vi /etc/xinetd.d/telnet并加入以下内容:# default: on# description: The telnet server serves telnet s ...

  4. iOS autolayout 代码,自定义间距

    最近换了新的项目组,然后这个项目组是纯代码,然后我就开始试着用代码去写适配,结果学艺不精,遇到个闪退,搜了一下发现几乎没有人遇到这个问题,后来发现其实就是我自己太粗心了. 我是这样写的 NSArray ...

  5. 【转】输入/输出流 - 全面掌握IO

    File类: 程序中操作文件和目录都可以使用File类来完成即不管是文件还是目录都是使用File类来操作的,File能新建,删除,重命名文件和目录,但File不能访问文件内容本身,如果需要访问文件本身 ...

  6. hive源码之新建一个coroutine

    最近由于项目需要读了一下云风老大的hive项目代码,因为对lua只有熟悉的水平,下面的东西必然多多错误:),只为记录. lua_State *sL = schedule_newtask(L); str ...

  7. 小型资源管理器,IO操作,读取和写入文件和目录的常用操作

    解决方案: 小总结: 用IO流,的file,DirectoryInfo的方法绑定Treeview控件上和删除,读取, 可以熟练掌握一下IO流 主页面: private void Form1_Load( ...

  8. [转]XSS现代WAF规则探测及绕过技术

    初始测试 1.使用无害的payload,类似<b>,<i>,<u>观察响应,判断应用程序是否被HTML编码,是否标签被过滤,是否过滤<>等等: 2.如果 ...

  9. MVC之路随记1--Filter的应用

    功能:MVC提供过滤器Filter,使开发者不用复杂的实现AOP而直接用Filter实现同样的功能. 实现:1.定义一个类实现ActionFilterAttribute,重载借口中的方法后在Contr ...

  10. Docker简明教程

    Docker简明教程 [编者的话]使用Docker来写代码更高效并能有效提升自己的技能.Docker能打包你的开发环境,消除包的依赖冲突,并通过集装箱式的应用来减少开发时间和学习时间. Docker作 ...