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

Страница: 465 из 528



При наличии приведенного выше определения интерфейса корректной была бы следующая реализация метода:

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 вслучае, если у отправителя имеются дополнительные данные для посылки, и S_FALSE , если пересылка закончена. Также отметим, что в данный код включена защита от некорректных реализации, которые не утруждают себя установкой переменной cFetched при возвращении S_OK ( S_OK означает, что все запрошенные элементы были извлечены).

Одно из преимуществ использования идиомы IEnum состоит в том, что она позволяет отправителю откладывать генерирование элементов массива. Рассмотрим следующее определение метода на IDL: HRESULT GetPrimes([in] long nMin, [in] long nMax, [out] IEnumLong **ppe);

Разработчик объекта может создать специальный класс, который генерирует по требованию простые числа и реализует интерфейс IEnumLong :

class PrimeGenerator : public IEnumLong {

LONG m_cRef;

// СОМ reference count

// счетчик ссылок СОМ

long m_nCurrentPrime;

// the cursor

// курсор long m_nMin;

// minimum prime value

// минимальное значение простого числа

long m_nMax;

// maximum prime value

// максимальное значение простого числа

public:

PrimeGenerator(long nMin, long nMax, long nCurrentPrime) : m_cRef(0), m_nMin(nMin), m_nMax(nMax),

m_nCurrentPrime(nCurrentPrime) { }

// IUnknown methods

// методы IUnknown

STDMETHODIMP QueryInterface(REFIID riid, void **ppv);

STDHETHODIMP_(ULONG) AddRef(void);

STDMETHODIMP_(ULONG) Release(void);

// IEnumLong methods

// методы IEnumLong

STDMETHODIMP Next(ULONG, long *, ULONG *);

STDMETHODIMP Skip(ULONG);

STDMETHODIMP Reset(void);

STDMETHODIMP Clone(IEnumLong **ppe);

};

Реализация генератора Next будет просто порождать запрошенное количество простых чисел:

STDMETHODIMP PrimeGenerator::Next(ULONG cElems, long *prgElems, ULONG *pcFetched) {

|< Пред. 463 464 465 466 467 След. >|

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