(转)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 简单实现父组件向子组件传值,简单来说就是子组件肆意妄为的调用父组件里后台返回的值
首先在于父子组件传值的方法很多,本人在这里只是简单描述一下一个组件里面引用了子组件,那么子组件如何才能获取父组件中后台返回的值呢? 首先调用组件相信大家都应该明白了(不明白的自己撸撸文档), < ...
随机推荐
- 面试复习(C++)之基数排序
#include <iostream> using namespace std; int maxbit(int *a,int n) { ;//一位 ;//十进制 ;i<n;i++) ...
- linux 内核邮件列表
第一节 - 一般性问题 1. 为什么有些时候使用“GNU/Linux"而另一些时候使用“Linux”? 答:在这个FAQ中,我们尝试使用“linux”或者“linux kernel”来表示内 ...
- 第二篇.Bootstrap起步
第二篇Bootstrap起步 我们可以在http://getbootstrap.com下载bootstrap的文件 点击左边的download bootstrap可以下载bootstrap的css,j ...
- 如何使用.NET开发全版本支持的Outlook插件产品(一)——准备工作
这半年一直在做Outlook的插件,因为不会VC++,所以想找一款基于.NET,用C#开发Outlook插件的技术方案.没想到,光技术选型这件事,就用各种技术手段验证了将近一个月,还花费了大量的精力做 ...
- 鼠标滚动div固定浮动-加锚点
页面: <div class="pa"> <div class="w-95-sl bdl-2"><a>标 ...
- 输出MYSQL所有SQL语句
在my.cnf中的mysqld段增加如下参数,然后重启MYSQL: log-output = FILE general_log = 1 general_log_file = "D:/Visu ...
- web前端教程之javascript创建对象的方法
今天给大家讲讲javascript基础教程中的javascript面向对象的技术,这一次我们深入的学习一下JavaScrip基于t面向对象之创建对象,关于面向对象的一些术语这里就不给大家介绍了,不了解 ...
- ACM 暴力搜索题 题目整理
UVa 129 Krypton Factor 注意输出格式,比较坑爹. 每次要进行处理去掉容易的串,统计困难串的个数. #include<iostream> #include<vec ...
- python wordcloud 对电影《我不是潘金莲》制作词云
上个星期五(16/11/18)去看了冯小刚的最新电影<我不是潘金莲>,电影很长,有点黑色幽默.看完之后我就去知乎,豆瓣电影等看看大家对于这部电影的评价.果然这是一部很有争议的电影,无论是在 ...
- HTTP2试用小记
原文:https://www.clarencep.com/2016/11/17/upgrade-nginx-to-support-http2/ 这两天把公司的网站升级到了全站https. 顺便瞄到了H ...