¿Vale la pena verificar si hay un puntero nulo en la implementación de QueryInterface ()?
-
07-07-2019 - |
Pregunta
IUnknown :: QueryInterface () recibe un parámetro nulo ** que indica una dirección donde colocar la interfaz recuperada.
STDMETHOD QueryInterface(/* [in] */ REFIID riid, /* [iid_is][out] */ void** ppvObject)
¿Debería la implementación de QueryInterface () verificar que este puntero sea nulo (e inmediatamente devolver E_POINTER) o simplemente escribir allí?
He visto mucho código relacionado con COM y en casi todas partes no se realiza ninguna verificación. Hipotéticamente, por supuesto, alguien podría pasar un puntero nulo como este parámetro, pero ¿es realmente necesario ese control?
Solución
Usted (la persona que llama) no necesita verificar que el puntero no sea NULL
.
Sin embargo, debe verificar el HRESULT
devuelto. El método devolverá E_POINTER
si el puntero de salida es NULL
y E_NOINTERFACE
si la interfaz no es compatible.
El destinatario de la llamada debe verificar que el puntero no sea NULL
y devolver E_POINTER
si es NULL
:
MSDN : Valor de retorno:
Este método devuelve
S_OK
si la interfaz es compatible, yE_NOINTERFACE
de lo contrario. SippvObject
esNULL
, este método devuelveE_POINTER
.
Otros consejos
De acuerdo con el documentos MSDN , QueryInterface devuelve S_OK, en cuyo caso el parámetro out se establecerá correctamente. O devuelve E_NOINTERFACE, en cuyo caso no se establecerá el parámetro de salida.
Devolverá E_POINTER si el vacío ** que pasa es NULL.
No me molestaría en buscar nulos, sino en comprobar el valor de retorno de IUnknown :: QueryInterface
Probablemente no haya ningún daño en la comprobación de nulo, pero dadas las garantías de la interfaz, parece una comprobación redundante.
Depende de qué tipo de objeto COM estás QI'ing (o qué aplicación te aloja). La mayoría de las veces, solo verificar el HRESULT debería ser suficiente. Si se trata de objetos de terceros (reemplazo de Explorer, etc.), probablemente también deba verificar NULL. Explorer hace esto y, por lo tanto, también debe hacerlo si desea evitar bloqueos en extensiones con errores: