Сущность технологии COM



         

Массивы - часть 14


HRESULT Method(SAFEARRAY **psa);

Отметим, что в определении IDL используется только один уровень косвенности; в то же время в соответствующем определении C++ используются два уровня косвенности. Рассмотрим следующее определение на IDL, задающее массив типа SAFEARRAY из коротких целых чисел:

HRESULT Method([in] SAFEARRAY(short) *psa);

Соответствующее определение на Visual Basic выглядело бы таким образом:

Sub Method(ByVal psa As Integer())

Отметим, что в варианте на Visual Basic не указано явно размерностей массива. Напомним, однако, что Visual Basic поддерживает массивы с фиксированной длиной.

Тип данных SAFEARRAY поддерживается весьма богатым набором API-функций, которые позволяют изменять размерность массивов и производить обход их содержимого переносимым образом. Для доступа к элементам типа SAFEARRAY СОМ предусматривает следующие вызовы API-функций:

// get a pointer to the actual array elements // получаем указатель на фактически элементы массива HRESULT SafeArrayAccessData([in] SAFEARRAY *psa, [out] void ** ppv);

// release pointer returned by SafeArrayAccessData // освобождаем указатель, возвращенный функцией SafeArrayAccessData HRESULT SafeArrayUnaccessData([in] SAFEARRAY *psa);

// Get number of dimensions // Получаем количество измерений ULONG SafeArrayGetDim([in] SAFEARRAY *psa);

// Get upper bound of a dimension // Получаем верхнюю границу измерения HRESULT SafeArrayGetUBound([in] SAFEARRAY *psa, [in] UINT nDim, [out] long *pUBound);

// Get lower bound of a dimension // Получаем нижнюю границу измерения HRESULT SafeArrayGetLBound([in] SAFEARRAY *psa, [in] UINT nDim, [out] long *pLBound);

Эти методы обеспечивают компактный и надежный способ доступа к текущему содержимому массива. Рассмотрим следующий код на IDL:

HRESULT Sum([in] SAFEARRAY(long) *ppsa, [out, retval] long *pSum);

Тогда следующая реализация метода будет вычислять сумму элементов массива типа SAFEARRAY, состоящего из длинных целых чисел (long integers):

STDMETHODIMP MyClass::Sum(SAFEARRAY **ppsa, long *pnSum) { assert(ppsa && *ppsa && pnSum); assert(SafeArrayGetDim(*ppsa) == 1); long iUBound, iLBound; // note that dimension indices are one-based // отметим, что индексы размерности начинаются с единицы HRESULT hr = SafeArrayGetUBound(*ppsa, 1, &iUBound); assert(SUCCEEDED(hr)); hr = SafeArrayGetLBound(*ppsa, 1, &iLBound); assert(SUCCEEDED(hr)); long *prgn = 0; hr = SafeArrayAccessData(*ppsa, (void**)&prgn); *pnSum = 0; for (long i = 0; i < iUBound - iLBound; i++) *pnSum += prgn[i]; SafeArrayUnaccessData(*ppsa); return S_OK; }




Содержание  Назад  Вперед