Сущность технологии СОМ. Библиотека программиста :: Бокс Дональд
Страница:
464 из 528
Чтобы применить эту идиому к приведенному выше определению метода, понадобится следующее определение интерфейса:
interface IEnumDouble : Unknown {
// pull a chunk of elements from the sender
// извлекаем порцию данных из отправителя
HRESULT Next([in] ULONG cElems, [out, size_is(cElems), length_is(*pcFetched)] double *prgElems, [out] ULONG *pcFetched);
// advance cursor past cElems elements
// переставляем курсор после элементов cElems
HRESULT Skip([in] cElems);
// reset cursor to first element
// возвращаем курсор на первый элемент
HRESULT Reset(void);
// duplicate enumerator's current cursor
// копируем текущий курсор нумератора
HRESULT Clone([out] IEnumDouble **pped);
}
Важно отметить, что интерфейс IEnum моделирует только курсор, а отнюдь не текущий массив. Имея такое определение интерфейса, исходное определение метода IDL:
HRESULT Sum([in] long cElems, [in, size_is(cElems)] double *prgd, [out, retval] double *pResult);
преобразуется следующим образом:
HRESULT Sum([in] IEnumDouble *ped, [out, retval] double *pResult);
Отметим, что подсчет элементов больше не является обязательным, так как получатель данных обнаружит конец массива, когда метод IEnumDouble::Next возвратит специальный HRESULT ( S_FALSE ).
При наличии приведенного выше определения интерфейса корректной была бы следующая реализация метода:
STDMETHODIMP MyClass::Sum(IEnumDouble *ped, double *psum) {
assert(ped && psum);
*psum = 0; HRESULT hr; do {
// declare a buffer to receive some elements
// объявляем буфер для получения нескольких элементов
enum {
CHUNKSIZE = 2048 };
double rgd[CHUNKSIZE];
// ask data producer to send CHUNKSIZE elements
// просим источник данных послать CHUNKSIZE элементов
ULONG cFetched;
hr = ped->Next(CHUNKSIZE, rgd, &cFetched);
// adjust cFetched to address sloppy objects
// настраиваем cFetched на исправление некорректных объектов
if (hr == S_OK) cFetched = CHUNKSIZE;
if (SUCCEEDED(hr))
// S_OK or S_FALSE
// S_OK или S_FALSE
// consume/use received elements
// потребляем/используем полученные элементы
for (ULONG n = О; п < cFetched; n++) *psum += rgd[n];
}
while (hr == S_OK);
// S_FALSE or error terminates
// завершается по S_FALSE или по ошибке
}
Отметим, что подпрограмма Next возвратит S_OK в
|< Пред. 462 463 464 465 466 След. >|