Проблема с D3D & COM - PullRequest
       43

Проблема с D3D & COM

1 голос
/ 28 февраля 2010

все интерфейсы D3D являются производными от интерфейса IUnknown в COM, поэтому я решил пойти простым путем для освобождения объектов 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 голосов
/ 28 февраля 2010

Обычно используемый способ работы с COM-ресурсами заключается в использовании RAII и разрешении вспомогательных классов, таких как ATL CComPtr или CComQIPtr, для максимально возможного подсчета ссылок. .

void f() {
    CComPtr<IDirect3DDevice> sp3dDev;
    getDevice(&sp3dDev);
    // ... do stuff
} // smart pointer gets destroyed, calls Release() if valid
3 голосов
/ 28 февраля 2010

Функция шаблона решает вашу проблему:

template<class T>
__inline bool SafeRelease(T*& pUnknown)
{
    if (pUnknown == NULL) return false;
    if (0 == pUnknown->Release()) 
        pUnknown = NULL;
    return true;
}
0 голосов
/ 28 февраля 2010

Я давно не работал с DirectX, но помню, что где-то в заголовках есть макрос SAFE_RELEASE. Поиск кода Google показывает, что он в dxutil.h.

0 голосов
/ 28 февраля 2010

Если бы вы могли делать то, что изначально писали, вы бы нарушили безопасность типов:

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

Очевидно, что присвоение bar значению unknown будет означать, что blah указывает на IUnknown, что нарушит безопасность типов.

Решение nobugz , вероятно, то, что вы хотите сделать, хотя я бы сказал, что установка этих указателей в NULL не повышает качество вашего кода. Если вам нужно убедиться, что другой код не будет Release несколько раз, вам, вероятно, следует исправить этот код, а не делать так, чтобы ошибочный код не заканчивался ошибкой.

...