Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to iterate through SAFEARRAY **

Tags:

c++

com

safearray

how to iterate through C++ safearray pointer to pointer and access its elements.

I tried to replicate the solution posted by Lim Bio Liong http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/022dba14-9abf-4872-9f43-f4fc05bd2602 but the strangest thing is that the IDL method signature comes out to be

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

instead of

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

Any ideas?

thanks in advance

like image 856
TrustyCoder Avatar asked Sep 18 '12 19:09

TrustyCoder


2 Answers

Safearrays are created with SafeArrayCreate or SafeArrayCreateVector, but as you ask about iterating over a SAFEARRAY, let's say you already have a SAFEARRAY returned by some other function. One way is to use SafeArrayGetElement API which is especially convenient if you have multidimensional SAFEARRAYs, as it allows, IMO, a bit easier specifying of the indices.

However, for vectors (unidimensional SAFEARRAY) it is faster to access data directly and iterate over the values. Here's an example:

Let's say it's a SAFEARRAY of longs, ie. 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);
like image 174
Zdeslav Vojkovic Avatar answered Oct 06 '22 00:10

Zdeslav Vojkovic


MSDN SafeArrayGetElement function gives you a code snippet on using SafeArrayGetElement to obtain individual object to array.

SAFEARRAY structure and SafeArray* functions explain the available API.

In ATL/MFC project you would want to use wrapper classes e.g. CComSafeArray to make things simpler and easier. See Simplifying SAFEARRAY programming with CComSafeArray on this.

like image 23
Roman R. Avatar answered Oct 06 '22 00:10

Roman R.