Как пройти через SAFEARRAY **

как выполнить итерацию с помощью указателя указателя на С++ для указателя и доступа к его элементам.

Я попытался реплицировать решение, отправленное Lim Bio Liong http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/022dba14-9abf-4872-9f43-f4fc05bd2602  но самое странное, что сигнатура метода IDL выходит

HRESULT __stdcall GetTestStructArray([out] SAFEARRAY ** test_struct_array);

вместо

HRESULT __stdcall GetTestStructArray([out] SAFEARRAY(TestStruct)* test_struct_array);

Любые идеи?

заблаговременно

Ответ 1

Сафари создаются с помощью SafeArrayCreate или SafeArrayCreateVector, но когда вы спрашиваете об итерации по SAFEARRAY, скажем, у вас уже есть SAFEARRAY, возвращаемый какой-либо другой функцией. Один из способов - использовать API SafeArrayGetElement, который особенно удобен, если у вас есть многомерные SAFEARRAY, поскольку это позволяет, IMO, немного легче указать индексы.

Однако для векторов (одномерный SAFEARRAY) быстрее обращаться к данным напрямую и перебирать значения. Вот пример:

Скажем, что это SAFEARRAY of long s, т.е. VT_I4

// get them from somewhere. (I will assume that this is done 
// in a way that you are now responsible to free the memory)
SAFEARRAY* saValues = ... 
LONG* pVals;
HRESULT hr = SafeArrayAccessData(saValues, (void**)&pVals); // direct access to SA memory
if (SUCCEEDED(hr))
{
  long lowerBound, upperBound;  // get array bounds
  SafeArrayGetLBound(saValues, 1 , &lowerBound);
  SafeArrayGetUBound(saValues, 1, &upperBound);

  long cnt_elements = upperBound - lowerBound + 1; 
  for (int i = 0; i < cnt_elements; ++i)  // iterate through returned values
  {                              
    LONG lVal = pVals[i];   
    std::cout << "element " << i << ": value = " << lVal << std::endl;
  }       
  SafeArrayUnaccessData(saValues);
}
SafeArrayDestroy(saValues);

Ответ 2

MSDN Функция SafeArrayGetElement дает фрагмент кода при использовании SafeArrayGetElement для получения отдельного объекта в массиве.

SAFEARRAY structure и SafeArray* функции объясняют доступный API.

В проекте ATL/MFC вы хотели бы использовать классы-оболочки, например. CComSafeArray, чтобы сделать вещи проще и проще. См. Упрощение программирования SAFEARRAY с помощью CComSafeArray.