addref/release语义的应用比COM技术要广泛得多。有一个简单的规则oneCreateObject()(或CreateTexture,或GetRenderTarget,或GetBackBuffer,等等......)必须面对one@ 987654325@, one AddRef() 必须面对 one Release()。
在 COM 中 IUnknown::Release() 返回对对象的引用数。它可能会欺骗您,您可以认为:
“嗯......我只是打电话给Release(),直到它返回0,我不会有任何泄漏。????利润!!!!!!111”AddRef 可能由 Direct3D 本身调用,也可能由您将此对象传递给的 3rd_party 库或您的应用程序之外的其他东西调用。 一个 Release 为 一个 AddRef。当您不再需要对象时,您应该调用Release,不要浪费系统资源。
你说:
在后台缓冲区上多次调用 Release 似乎不会造成任何损害
这没有任何意义。可能是宇宙太喜欢你了,或者你太幸运了,没有从 D3D 中得到例外。
如果您愿意使用智能指针(例如CComPtr),它们可以让您的生活更轻松。在这种情况下,您不需要显式调用Release,如果将其分配给某个对象,则会在CComPtr dtor 中调用它。
void get_surface(IDirect3DDevice9 *pDevice)
{
IDirect3DSurface9 *surf0;
IDirect3DSurface9 *surf1;
CComPtr<IDirect3DSurface9> surf2;
CComPtr<IDirect3DSurface9> surf3;
CComPtr<IDirect3DSurface9> surf4;
pDevice->GetRenderTarget( 0, surf0 ); // surface reference counter incremented, you should call Release() for this
surf1 = surf0; // surface reference count is not incremented, you shouldn't call Release() for this
pDevice->GetRenderTarget( 0, surf2 ); // surface reference counter incremented
CComPtr<IDirect3DSurface9> surf3 = surf0; // surface reference counter incremented
surf0->Release(); // release for pDevice->GetRenderTarget( 0, surf0 );
surf2.Release(); // .Release() used not ->Release() - it is important
surf4.Release(); // nothing happens because surf4 == 0
} // surf3.Release() is called in surf3 destructor
您也可以#define D3D_DEBUG_INFObefore 包括直接 3d 标头并切换到调试 d3d 运行时。它有助于发现 d3d 应用程序中的漏洞。
愿CComPtr原力与你同在。