Сущность технологии СОМ. Библиотека программиста   ::   Бокс Дональд

Страница: 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 След. >|

Java книги

Контакты: [email protected]