是否值得在 QueryInterface() 实现中检查空指针?
-
07-07-2019 - |
题
IUnknown::QueryInterface() 传递一个 void** 参数,表示放置检索到的接口的地址。
STDMETHOD QueryInterface(/* [in] */ REFIID riid, /* [iid_is][out] */ void** ppvObject)
QueryInterface() 的实现应该检查该指针是否为空(然后立即返回 E_POINTER)还是直接写入该指针?
我见过很多与 COM 相关的代码,几乎所有地方都没有执行检查。假设有人当然可以传递空指针作为这个参数,但是这样的检查真的需要吗?
解决方案
您(调用者)不需要检查指针是否为 NULL
。
但是,您应该检查返回的 HRESULT
。如果输出指针是 NULL
,那么该方法将返回 E_POINTER
,如果接口不受支持,则返回 E_NOINTERFACE
。
被调用者应该检查指针是否为 NULL
并返回 E_POINTER
,如果它是 NULL
:
MSDN :返回值:
如果支持接口,则此方法返回
S_OK
,否则返回E_NOINTERFACE
。如果ppvObject
是NULL
,则此方法返回E_POINTER
。
其他提示
根据 MSDN docs , QueryInterface返回S_OK,在这种情况下将正确设置out参数。或者它返回E_NOINTERFACE,在这种情况下,不会设置out参数。
如果传入的void **为NULL,它将返回E_POINTER。
我不打算检查null,而是检查IUnknown :: QueryInterface的返回值
检查null可能没什么坏处,但考虑到接口的保证,它似乎是一个冗余检查。
这取决于您正在 QI'ing 的 COM 对象类型(或者托管您的应用程序)。大多数时候,只需检查 HRESULT 就足够了。如果您正在处理第 3 方对象(Explorer 替换等),您可能还应该检查 NULL。资源管理器会执行此操作,因此如果您想避免有缺陷的扩展程序崩溃,您还需要这样做: