Какой HRESULT вернуть, если предоставленный буфер слишком мал? - PullRequest
4 голосов
/ 18 февраля 2011

У меня есть функция в IUnknown -обработанном COM-интерфейсе:

HRESULT GetPassword( [in] long bufferLength, [out] WCHAR* buffer );

, и контракт заключается в том, что реализация должна проверить, достаточно ли большой буфер для хранения извлекаемой строки.Если буфер достаточно велик, строка копируется и возвращается S_OK, в противном случае функция вернет сообщение об ошибке.

Однако я не могу найти подходящее значение HRESULT для этого.E_UNEXPECTED кажется довольно глупым и бесполезным.Самое близкое, что я нашел, это DISP_E_BUFFERTOOSMALL, но похоже, что это только для IDispatch -обработанных интерфейсов.

Какой HRESULT я должен вернуть, если предоставленный буфер слишком мал?

Ответы [ 4 ]

4 голосов
/ 19 февраля 2011

Вы не можете вернуть DISP_E_ * ошибки, вы не реализуете IDispatch.E_INVALIDARG здесь правильный, он даже однозначный, что не часто случается.Всегда реализуйте ISupportErrorInfo для создания хороших сообщений об ошибках, ATL делает это тривиальным с помощью метода Error ().

1 голос
/ 18 февраля 2011

Вы не должны возвращать ошибку. Вы должны добиться успеха, заполнить буфер тем, что вы можете, и через другой параметр вернуть, насколько большим должен быть буфер.

Если вы не сделаете это таким образом, как вызывающая сторона обнаружит, какой большой буфер выделяется? Вы серьезно не хотите, чтобы они вызывали повторно, с постепенно увеличивающимися буферами, пока они не достигнут значения, которое достаточно? Я бы не хотел использовать такой интерфейс!

1 голос
/ 18 февраля 2011

Если вы все еще можете что-то с этим сделать, вам следует подумать об изменении интерфейса, чтобы он возвращал BSTR вместо WCHAR*.Это упрощает многие вещи.

Иногда вы можете, а иногда нет.

Кредит должен идти на @tenfour, чтобы предложить это.Поскольку вы не можете публиковать и пересылать свои голоса кому-то еще, я публикую в вики сообщества .

1 голос
/ 18 февраля 2011

Как бы глупо это ни звучало, E_INVALIDARG, пожалуй, ваш лучший выбор, если говорить технически. Существует не так много стандартных HRESULT, которые являются более конкретными для аргументов. Существует также E_POINTER, но это, вероятно, будет более запутанным.

Я бы рассмотрел использование DISP_E_BUFFERTOOSMALL. Это будет интуитивно понятно для вызывающих абонентов, и единственный риск заключается в том, что они не распознают его, поскольку он не входит в стандартный набор общих значений HRESULT. Я думаю, что это довольно небольшой риск для довольно маленькой проблемы:)

...