p指针->AddRef() 和 p指针->Relase()
来源:互联网 发布:1到100偶数积的编程 编辑:程序博客网 时间:2024/06/05 04:55
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()。
在本函数,有三处这样的语句:pMeshContainer->MeshData.pMesh = pMesh;pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;pMesh->AddRef();……
pMeshContainer->pSkinInfo = pSkinInfo;pSkinInfo->AddRef();pMeshContainer->pOrigMesh = pMesh;pMesh->AddRef();……
将来在DestroyMeshContainer()中,要释放这些指针:……
SAFE_RELEASE( pMeshContainer->MeshData.pMesh );SAFE_RELEASE( pMeshContainer->pSkinInfo );SAFE_RELEASE( pMeshContainer->pOrigMesh );由于这些指针值的创建、更改等都是用户自己经营的,所以务必要加前后吻合,在CreateMeshContainer()中AddRef(),在DestroyMeshContainer()中Release()。
- p指针->AddRef() 和 p指针->Relase()
- 指针 *p++和*++p
- 指针中的 &p, p, *p
- 指针++*p++
- 指针P
- 指针p,*p,&p之间的区别
- 指针p,*p,&p之间的区别
- 指针中*p,p,&p的理解
- 指针p+1 和&p[1]的差异
- 关于指针char *p和数组char p[] 的区别
- jstring转char*、指针p+i和&p[i]一样
- C语言之指针*p++和*(p++)区别
- C语言指针的*p++ ,*p(++), (*p)++,*++p的使用
- C语言指针的*p++ ,*p(++), (*p)++,*++p的使用
- [C]指针(*p)[10]
- delete p指针
- 二级指针**P
- int **p二级指针
- Java数组
- 使用xargs与awk联合使用批量杀进程
- 百分之二
- 堆栈转帖
- 【转】论编程的最后期限
- p指针->AddRef() 和 p指针->Relase()
- 继续昨天SQL
- 生成随机数
- 数据挖掘和推荐引擎开源项目列表 (欢迎补充)
- 待定
- Linux-2.6.32.2内核在mini2440上的移植(三)---DM9000网卡驱动移植
- 很全的英语短语,可以防止你英文退化
- Gridview
- 。◕‿◕。 【IP\Bash\环境变量\mount挂载\TFTP和NFS】各种设置