简体   繁体   中英

How to iterate through 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

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 long s, 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);

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 eg CComSafeArray to make things simpler and easier. See Simplifying SAFEARRAY programming with CComSafeArray on this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM