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

ОглавлениеДобавить в закладки К обложке

HRESULT GetPrimes([in] long nStart, [in] long nEnd, [out] SAFEARRAY(long) *ppsa);

следующее определение метода на C++ возвращает вызывающей программе массив типа SAFEARRAY, размещенный в вызываемом методе:

STDMETHODIMP MyClass::GetPrimes (long nMin, long nMax, SAFEARRAY **ppsa)

{

assert(ppsa);

UINT cElems = GetNumberOfPrimes(nMin, nMax);

*ppsa = SafeArrayCreateVector(VT_I4, 0, cElems);

assert(*ppsa);

long *prgn = 0;

HRESULT hr = SafeArrayAccessData(*ppsa, (void**)&prgn);

assert(SUCCEEDED(hr));

for (UINT i=0; i < cElems; i++)

prgn[i] = GetNextPrime(i ? prgn[1 – 1] : nMin);

SafeArrayUnaccessData(*ppsa);

return S_OK;

}

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

Function GetSumOfPrimes(ByVal nMin as Long, ByVal nMax as Long) as Long

Dim arr() as Long

Dim n as Variant

Objref.GetPrimes nMin, nMax, arr

GetSumOfPrimes = 0

for each n in arr

GetSumOfPrimes = GetSumOfPrimes + n

Next n

End Function

что соответствует следующему коду на C++:

long GetSumOfPrimes (long nMin, long nMax)

{

SAFEARRAY *pArray = 0;

HRESULT hr = g_pObjRef->GetPrimes(nMin, nMax, &pArray);

assert(SUCCEEDED(hr) && SafeArrayGetDim(pArray) == 1);

long *prgn = 0;

hr = SafeArrayAccessData(pArray, (void**)&prgn);

long iUBound, iLBound, result = 0;

SafeArrayGetUBound(pArray, 1, &iUBound);

SafeArrayGetLBound(pArray, 1, &iLBound);

for (long n = iLBound; n <= iUBound: n++)

result += prgn[n];

SafeArrayUnaccessData(pArray);

SafeArrayDestroy(pArray);

return n;

}

Отметим, что вызывающая программа ответственна за освобождение ресурсов, выделенных для SAFEARRAY-массива, возвращенного как [out]-параметр. Вызов функции SafeArrayDestroy корректно освобождает всю память и все ресурсы, удерживаемые структурой SAFEARRAY.


Логин
Пароль
Запомнить меня