Problema con D3D & COM
-
23-09-2019 - |
Pregunta
todas las interfaces D3D se derivan de interfaz IUnknown de COM, así que aunque me gustaría tener una ruta fácil para liberar objetos D3D y usar algo como esto:
__inline BOOL SafeRelease(IUnknown*& pUnknown)
{
if(pUnknown != NULL && FAILED(pUnknown->Release()))
return FALSE;
pUnknown = NULL;
return TRUE;
}
esto no funciona, sin embargo, como el compilador generará errores de conversión de tipo no válido (s), cuando trato de usarlo. la única manera de evitar que se me ocurrió fue lo siguiente:
__inline BOOL SafeRelease(void* pObject)
{
IUnknown* pUnknown = static_cast<IUnknown*>pObject;
if(pUnknown != NULL && FAILED(pUnknown->Release()))
return FALSE;
return TRUE;
}
pero luego me suelta algunas funciones y también se ve (y es) muy poco fiables. ¿Hay una mejor manera de hacer esto? algo que obras como mi primer ejemplo serían óptimos, aunque me gustaría evitar el uso de macros (si es posible)
Solución
Una función de plantilla resuelve su problema:
template<class T>
__inline bool SafeRelease(T*& pUnknown)
{
if (pUnknown == NULL) return false;
if (0 == pUnknown->Release())
pUnknown = NULL;
return true;
}
Otros consejos
La ruta comúnmente adoptado para hacer frente a los recursos COM es emplear RAII y dejar ayudante clases como ATL CComPtr
o CComQIPtr
recuento de referencias mango para usted lo más lejos posible.
void f() {
CComPtr<IDirect3DDevice> sp3dDev;
getDevice(&sp3dDev);
// ... do stuff
} // smart pointer gets destroyed, calls Release() if valid
Si usted podría hacer lo que escribió originalmente, entonces sería violar la seguridad de tipos:
IDirect3DDevice *blah;
IUnknown *bar;
IUnknown *&unknown= blah;
unknown= bar;
Es evidente que la asignación de bar
a unknown
significaría que los puntos de blah
a un IUnknown
, lo que violaría la seguridad de tipos.
de nobugz solución es probablemente lo que quiere hacer, aunque lo haría argumentan que la fijación de los punteros a NULL no aumenta la calidad de su código. Si es necesario asegurarse de que no serán otros códigos Release
varias veces, probablemente debería fijar ese código en lugar de hacer el código con errores no falla.
No he trabajado con DirectX desde hace tiempo pero recuerdo que en alguna parte tiene una macro SAFE_RELEASE
en ella de cabeceras. Google de búsqueda de código muestra que está en dxutil.h
.