Vale la pena controllare il puntatore null nell'implementazione di QueryInterface ()?
-
07-07-2019 - |
Domanda
IUnknown :: QueryInterface () viene passato un parametro void ** che indica un indirizzo dove collocare l'interfaccia recuperata.
STDMETHOD QueryInterface(/* [in] */ REFIID riid, /* [iid_is][out] */ void** ppvObject)
L'implementazione di QueryInterface () dovrebbe verificare che questo puntatore sia null (e quindi restituire immediatamente E_POINTER) o semplicemente scrivere lì?
Ho visto un sacco di codice relativo a COM e quasi ovunque non viene eseguito alcun controllo. Ipoteticamente qualcuno potrebbe ovviamente passare un puntatore null come questo parametro, ma è davvero necessario un tale controllo?
Soluzione
Tu (il chiamante) non devi controllare il puntatore per non essere NULL
.
Tuttavia, è necessario controllare il HRESULT
restituito. Il metodo restituirà E_POINTER
se il puntatore di output è NULL
e E_NOINTERFACE
se l'interfaccia non è supportata.
Il chiamante dovrebbe controllare il puntatore per non essere NULL
e restituire E_POINTER
se è NULL
:
MSDN : Valore restituito:
Questo metodo restituisce
S_OK
se l'interfaccia è supportata eE_NOINTERFACE
in caso contrario. SeppvObject
èNULL
, questo metodo restituisceE_POINTER
.
Altri suggerimenti
Secondo i documenti MSDN , QueryInterface restituisce S_OK, nel qual caso il parametro out verrà impostato correttamente. Oppure restituisce E_NOINTERFACE, nel qual caso il parametro out non verrà impostato.
Restituirà E_POINTER se il vuoto ** che passi è NULL.
Non mi preoccuperei di controllare null, piuttosto controllerei il valore di ritorno da IUnknown :: QueryInterface
Probabilmente non c'è nulla di male nel controllo di null, ma date le garanzie dell'interfaccia sembra un controllo ridondante.
Dipende dal tipo di oggetto COM che stai QI (o dall'app che ti ospita). Il più delle volte basta controllare HRESULT dovrebbe essere sufficiente. Se hai a che fare con oggetti di terze parti (sostituzione Explorer ecc.) Probabilmente dovresti anche controllare NULL. Explorer lo fa, e quindi è necessario farlo anche se si desidera evitare arresti anomali nelle estensioni con errori: