QueryInterface()実装でnullポインターをチェックする価値はありますか?
-
07-07-2019 - |
質問
IUnknown :: QueryInterface()には、取得したインターフェイスを配置するアドレスを示すvoid **パラメーターが渡されます。
STDMETHOD QueryInterface(/* [in] */ REFIID riid, /* [iid_is][out] */ void** ppvObject)
QueryInterface()の実装は、このポインターがnullであるかどうかを確認し(すぐにE_POINTERを返します)、そこに書き込むだけですか?
多くのCOM関連のコードを見てきましたが、ほとんどどこでもチェックは実行されません。仮に誰かがこのパラメーターとしてヌルポインターを渡すこともできますが、そのようなチェックは本当に必要ですか?
解決
あなた(呼び出し元)は、ポインターが NULL
でないことを確認する必要はありません。
ただし、返された HRESULT
を確認する必要があります。このメソッドは、出力ポインターが NULL
の場合は E_POINTER
を返し、インターフェイスがサポートされていない場合は E_NOINTERFACE
を返します。
呼び出し先は、ポインターが NULL
でないことを確認し、 NULL
の場合は E_POINTER
を返す必要があります。
MSDN :戻り値:
このメソッドは、インターフェイスがサポートされている場合は
S_OK
を返し、そうでない場合はE_NOINTERFACE
を返します。ppvObject
がNULL
の場合、このメソッドはE_POINTER
を返します。
他のヒント
MSDNドキュメントによると、 QueryInterfaceは、S_OKを返します。この場合、outパラメーターは正しく設定されます。または、E_NOINTERFACEを返します。この場合、outパラメーターは設定されません。
渡したvoid **がNULLの場合、E_POINTERを返します。
nullをチェックするのではなく、IUnknown :: QueryInterfaceからの戻り値をチェックします
nullのチェックにおそらく害はありませんが、インターフェイスの保証を考えると、冗長チェックのように見えます。
QIを実行しているCOMオブジェクトの種類(またはホストしているアプリ)によって異なります。ほとんどの場合、HRESULTをチェックするだけで十分です。サードパーティのオブジェクト(Explorerの置き換えなど)を扱っている場合は、おそらくNULLもチェックする必要があります。 Explorerはこれを行うため、バグのある拡張機能でのクラッシュを回避する場合にも必要です。