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

时间: 2024-11-09 06:48:22

(转)COM组件里的AddRef()的相关文章

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

在入口main.js里构建scss是通过引入模块的方式 import './assets/_reset.scss'; import './assets/_flex.scss'; import './assets/_functions.scss'; 在.vue组件里是单独构建的 <style lang="scss" scoped> img { width: rem(300px); } #product, .gallery, .detail { width: rem(750px

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

前段时间在用MUI的时候,Table组件出现复选框不能选的bug(描述: 点击复选框,点击事件会触发,复选框勾选状态无变化). 解决方法: 用CheckBox组件代替Table组件自带的复选框. 解决思路: 1.将CheckBox分为两种,一种是表头里的全选框(以下称全选框),一种是列表行里普通的复选框(以下称普通框): 2.将普通框进行单独封装(原因: 1.便于单个普通框自己管理自己的勾选状态,2.当全选框的勾选状态发生变化时,可以通过props将全选框的状态赋给它,从而实现全选的功能): 关

添加删除Windows组件里没有IIS(Internet信息服务)项的解决方法

现在,安装操作系统,对于个人用户而言基本都是用Ghost的,用原盘安装的,已经很少了 但是,使用克隆盘安装的系统,基本上都是没有安装IIS(Internet信息服务)的,对于做开发测试的人来说,是很不方便的,通常需要自己在 “添加/删除Windows组件” 里面,把IIS重新装上. IIS的独立安装包,已经很普遍了,网上N多,也省去了找原始系统安装盘的麻烦,很是方便,但是,有些Ghost的系统,为了精简和瘦身,对系统的一些默认设置进行了更改,隐藏和消减了一些安装项,这其中就包括IIS:使得在“添

vue组件里定时器销毁问题

解决方案1: data() { return { timer: null // 定时器名称 } }, this.timer = (() => { // 某些操作 }, 1000) 最后在beforeDestroy()生命周期内清除定时器: beforeDestroy() { clearInterval(this.timer); this.timer = null; } 方案1有两点不好的地方: 它需要在这个组件实例中保存这个 timer,如果可以的话最好只有生命周期钩子可以访问到它.这并不算严重

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

首先在于父子组件传值的方法很多,本人在这里只是简单描述一下一个组件里面引用了子组件,那么子组件如何才能获取父组件中后台返回的值呢? 首先调用组件相信大家都应该明白了(不明白的自己撸撸文档), <info-head :orderInfo="orderInfo" :changePrice="changePrice"></info-head> 上面的是父组件中引用的子组件,其中orderInfo为父组件中定义的接收后台返回的值需要向平常一样的去定义

vue.js学习之组件数据流详解

本文和大家分享的主要是vue.js组件数据流相关内容,一起来看看吧,希望对大家学习vue.js有所帮助. 一.组件 组件,可以说是现代前端框架中必不可少的组成部分.使用组件,不仅能极大地提高代码的复用率和开发者的开发效率,对于代码后期的维护也有着非常重要的意义.前端开发,由于历史遗留原因,WebComponent 虽然好用,但其发展情况却受到极大地限制,和很多新兴的前端技术一样,可望而不可即.基于这样的情况,聪明的开发者们尝试通过框架内部集成相应的功能来完成组件化,各种现代前端框架基本上都有各自

Vue学习笔记入门篇——组件的使用

本文为转载,原文:Vue学习笔记入门篇--组件的使用 组件定义 组件 (Component) 是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展. 组件使用 注册 注册一个全局组件,你可以使用 Vue.component(tagName, options).组件在注册之后,便可以在父实例的模块中以自定义元素 的形式使用.

组件化设计与开发

http://colachan.com/post/3545 终于迎来一期特刊.最近打算在公司内部做一个分享,讲的是组件化的设计与开发的思维方式.准备完演讲资料,发现这完全可以改成一篇文章.藏着掖着不合适,发出来分享给有需求的朋友吧,就当是个试讲了,希望大家帮忙指出错误. 下载地址:https://www.jianguoyun.com/p/DY1Z3bEQwKOaBhimoyg 由于本文首先是以keynote的形式诞生的,其中还有动画和视频,所以我比较推荐大家直接下载keynote文件(也存了PP

COM组件(ATL篇)

目录 第1章创建进程内组件    1 1.1 目标    1 1.2 创建项目    3 1.2.1 VC++6.0    3 1.2.2 VC++2010    5 1.3 增加COM类    6 1.3.1 VC++6.0    6 1.3.2 VC++2010    8 1.3.3 项目结构    12 1.4 增加方法    13 1.4.1 VC++6.0    13 1.4.2 VC++2010    14 1.5 增加属性    16 1.5.1 VC++6.0    16 1.5