D3D&的问题COM

时间:2010-02-28 08:37:58

标签: c++ com visual-c++ direct3d iunknown

所有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 个答案:

答案 0 :(得分:4)

处理COM资源的常用途径是使用RAII并让ATL CComPtrCComQIPtr之类的辅助类尽可能地处理引用计数。

void f() {
    CComPtr<IDirect3DDevice> sp3dDev;
    getDevice(&sp3dDev);
    // ... do stuff
} // smart pointer gets destroyed, calls Release() if valid

答案 1 :(得分:3)

模板功能解决了您的问题:

template<class T>
__inline bool SafeRelease(T*& pUnknown)
{
    if (pUnknown == NULL) return false;
    if (0 == pUnknown->Release()) 
        pUnknown = NULL;
    return true;
}

答案 2 :(得分:0)

如果你能做你最初写的东西,那么你会违反类型安全:

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

显然,将bar分配给unknown意味着blah指向IUnknown,这会违反类型安全。

nobugz's solution可能是您想要做的,虽然我认为将这些指针设置为NULL并不会提高代码的质量。如果您需要确保其他代码不会多次Release,那么您可能应该修复该代码而不是使错误代码失败。

答案 3 :(得分:0)

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