1

正式には、関数が成功しない限り、COM 関数からのパラメーターを使用しないでください。これは、パラメーターが使用できる[out]かどうかを確認する方法が (少なくとも) 3 つあることを意味します。[out]

次のインターフェースを検討してください

interface IFoo : IUnknown {
    HRESULT GetOtherFoo([out] IFoo** ppFoo);
    HRESULT Bar();
};

次のうち、どの方法を使用することをお勧めしますか?

1.戻り値の確認

CComPtr<IFoo> other;
HRESULT hr = foo->GetOtherFoo(&other);
if (SUCCEEDED(hr)) 
    other->Bar();

のバグがポインター IFooの逆参照を引き起こす可能性があるため、これは私を少し緊張させます。NULL

2.出力パラメータを確認する

これは、メソッドが失敗した場合にパラメーターを変更してはならないという事実に依存し[out]ます (パラメーターが変更された場合 <==> 使用しても安全です)。

CComPtr<IFoo> other;
foo->GetOtherFoo(&other);
if (other) 
    other->Bar();

とにかく、この種のことが起こることに注意してくださいCComPtr. のデストラクタはRelease、ポインタがNULLそうでない場合に呼び出されるので、ガベージになることはありません.

3. 偏執的な方法、両方にチェックを入れる

CComPtr<IFoo> other;
HRESULT hr = foo->GetOtherFoo(&other);
if (SUCCEEDED(hr) && other) 
    other->Bar();

私の意見では、これは少し冗長です。


PS関連の質問を参照してください。

4

2 に答える 2

2

成功した HRESULT を返し、出力パラメータの一部を NULL に設定する COM サーバー メソッドはあまり一般的ではありません。これが使用されるいくつかのケース (IClientSecurity::QueryBlanket が頭に浮かびます) がありますが、通常、メソッドが正常に返された場合、クライアントはすべての出力パラメーターが非 NULL であると想定する場合があります。

結局のところ、メソッドがどのように文書化されるかの問題です。ただし、デフォルトの場合、1. が安全な方法であると考えます。

于 2009-05-04T19:47:16.817 に答える