1

所有的 D3D 接口都派生自 COM 的 IUnknown 接口,所以我会采取一种简单的方法来释放 D3D 对象并使用类似这样的东西:

__inline BOOL SafeRelease(IUnknown*& pUnknown)
{
    if(pUnknown != NULL && FAILED(pUnknown->Release()))
        return FALSE;

    pUnknown = NULL;
    return TRUE;
}

但这不起作用,因为当我尝试使用它时,编译器会生成无效的类型转换错误。我能想到的唯一方法是:

__inline BOOL SafeRelease(void* pObject)
{
    IUnknown* pUnknown = static_cast<IUnknown*>pObject;
    if(pUnknown != NULL && FAILED(pUnknown->Release()))
        return FALSE;

    return TRUE;
} 

但后来我失去了一些功能,它也看起来(并且)非常狡猾。有一个更好的方法吗?像我的第一个示例一样工作的东西将是最佳的,尽管我想避免使用任何宏(如果可能的话)

4

4 回答 4

4

处理 COM 资源的常用方法是使用 RAII,并尽可能让 ATL 等辅助类CComPtrCComQIPtr为您处理引用计数。

void f() {
    CComPtr<IDirect3DDevice> sp3dDev;
    getDevice(&sp3dDev);
    // ... do stuff
} // smart pointer gets destroyed, calls Release() if valid
于 2010-02-28T09:23:13.787 回答
3

模板函数可以解决您的问题:

template<class T>
__inline bool SafeRelease(T*& pUnknown)
{
    if (pUnknown == NULL) return false;
    if (0 == pUnknown->Release()) 
        pUnknown = NULL;
    return true;
}
于 2010-02-28T08:55:07.553 回答
0

如果您可以执行您最初编写的操作,那么您将违反类型安全:

IDirect3DDevice *blah;
IUnknown *bar;
IUnknown *&unknown= blah;
unknown= bar;

显然,分配bartounknown意味着blah指向 a IUnknown,这将违反类型安全。

nobugz 的解决方案可能是您想要做的,尽管我认为将这些指针设置为 NULL 不会提高代码的质量。如果您需要确保其他代码不会Release多次出现,您可能应该修复该代码,而不是让有错误的代码不会失败。

于 2010-02-28T09:00:49.843 回答
0

我有一段时间没有使用 DirectX,但我记得它SAFE_RELEASE的标题中有一个宏。谷歌代码搜索显示它在dxutil.h.

于 2010-02-28T09:04:11.390 回答