Проблема с D3D и COM
-
23-09-2019 - |
Вопрос
все интерфейсы 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
.