Как мне проверить, можно ли использовать [out] params в COM? - PullRequest
1 голос
/ 04 мая 2009

Официально не следует использовать параметры [out] из функций COM, если только функция не выполнена успешно. Это означает, что существует (как минимум) три способа проверить, можно ли использовать параметр [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();

Это немного многословно, на мой взгляд.


P.S. См. связанный вопрос .

Ответы [ 2 ]

2 голосов
/ 05 мая 2009

Если вы хотите написать больше проверок и сделать код немного медленнее, чтобы сделать его более надежным, вариант 3 для вас. Поскольку вы ожидаете, что в COM-сервере есть ошибки, вполне разумно проверить их.

2 голосов
/ 04 мая 2009

Методы COM-сервера, которые возвращают успех HRESULT, но устанавливают для некоторых из своих выходных параметров значение NULL, не очень распространены. Есть несколько случаев (на ум приходит IClientSecurity :: QueryBlanket), где это используется, но обычно клиент может ожидать, что все выходные параметры будут отличны от NULL, если метод возвращен успешно.

В конце концов, вопрос заключается в том, как метод документирован. Однако в случае по умолчанию я бы посчитал 1. безопасным путем.

...