简体   繁体   中英

Problem with D3D & COM

all the D3D interfaces are derived from COM's IUnknown interface, so I though I'd take an easy route for releasing D3D objects and use something like this:

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

    pUnknown = NULL;
    return TRUE;
}

this doesn't work though, as the compiler will generate invalid type conversion error(s), when I try to use it. the only way around it I could think of was this:

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

    return TRUE;
} 

but then I loose some functionality and it also looks(and is) very dodgy. is there a better way to do this? something that works like my first example would be optimal, though I would like to avoid using any macros(if its possible)

The commonly taken route for dealing with COM resources is to employ RAII and let helper classes like ATLs CComPtr or CComQIPtr handle reference counting for you as far as possible.

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

A template function solves your problem:

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

If you could do what you originally wrote, then you would violate type safety:

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

Clearly, assigning bar to unknown would mean that blah points to an IUnknown , which would violate type safety.

nobugz's solution is probably what you want to do, although I would argue that setting those pointers to NULL doesn't increase the quality of your code. If you need to ensure that other code won't Release multiple times, you probably should go fix that code rather than making buggy code not fail.

I haven't worked with DirectX in a while but I remember it has a SAFE_RELEASE macro somewhere in it's headers. Google code search shows it's in dxutil.h .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM