Вопрос

все интерфейсы 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;
} 

но затем я теряю некоторую функциональность, и это также выглядит (и есть) очень сомнительно.есть ли лучший способ сделать это?что-то, что работает подобно моему первому примеру, было бы оптимальным, хотя я бы хотел избежать использования каких-либо макросов (если это возможно).

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top