Стоит ли проверять нулевой указатель в реализации QueryInterface()?
IUnknown::QueryInterface() передается параметр void**, обозначающий адрес, куда поместить извлеченный интерфейс.
STDMETHOD QueryInterface(/* [in] */ REFIID riid, /* [iid_is][out] */ void** ppvObject)
Должна ли реализация QueryInterface () проверять этот указатель на нулевое значение (а затем немедленно возвращать E_POINTER) или просто писать туда?
Я видел много кода, связанного с COM, и почти везде проверка не выполняется. Гипотетически кто-то может передать нулевой указатель в качестве этого параметра, но нужна ли такая проверка?
3 ответа
Вам (звонившему) не нужно проверять указатель на отсутствие NULL
,
Тем не менее, вы должны проверить возвращенный HRESULT
, Метод вернется E_POINTER
если выходной указатель NULL
а также E_NOINTERFACE
если интерфейс не поддерживается.
Вызываемый должен проверить указатель на отсутствие NULL
и вернуться E_POINTER
если это NULL
:
MSDN: возвращаемое значение:
Этот метод возвращает
S_OK
если интерфейс поддерживается, иE_NOINTERFACE
иначе. ЕслиppvObject
являетсяNULL
этот метод возвращаетE_POINTER
,
Согласно документам MSDN, QueryInterface либо возвращает S_OK, в этом случае параметр out будет установлен правильно. Или он возвращает E_NOINTERFACE, в этом случае параметр out не будет установлен.
Он вернет E_POINTER, если void**, который вы передаете, равен NULL.
Я бы не стал проверять наличие нуля, скорее я бы проверил возвращаемое значение из IUnknown::QueryInterface
Вероятно, нет ничего плохого в проверке на null, но с учетом гарантий интерфейса это выглядит как избыточная проверка.
Это зависит от того, какой тип COM-объекта вы используете (или какое приложение размещает вас). В большинстве случаев достаточно просто проверить HRESULT. Если вы имеете дело с объектами сторонних производителей (замена Проводника и т. Д.), Вам, вероятно, следует также проверить NULL Проводник делает это, и поэтому вам нужно также, если вы хотите избежать сбоев в ошибочных расширениях: