A Simple SafeArray Wrapper
The CSafeArray class is a wrapper for the SAFEARRAY datatype. The encapsulated member can be initialized using the Init function or using the constructor which takes the number of dimensions and the array of bounds information.
HRESULT Init(long lnoDims, VARENUM vt, long* lBounds)
The first parameter is the number of dimensions of the array which is to be created. The second parameter is the array element type. It can be any of the variant types like VT_BSTR, VT_VARIANT etc. The third parameter is used to pass in the SAFEARRAYBOUND information for all the dimension. For eg. if a 2 dimensional array with 2 rows and 3 cols has to be created, the lBounds array should be of size 4.
long lBounds[4] = {0, 3, 0, 2} // LBound and cElements info for each dimension.
Notice that the column information is given first. Crazy safearrays take the dimensions in the reverse order. The least significant dimension has to be given last.
Once the array is created using either the constructor or the Init funtion, the array elements can be retrieved or set using the following functions
HRESULT GetElement(long* lIndex, VARIANT* pvtElement)
HRESULT SetElement(long* lIndex, VARIANT vtElement)
Again when specifying the lIndex array, the least significant dimension should be given last.
eg For accessing the element in the 2nd row and 3rd column of a 2 dimensional array, lIndex should be {2, 1}.
The number of elements, the lowerbound or upper bound in any dimension can be retreived using the following functions.
long GetElementCount(long lDim)
long GetLowerBound(long lDim) and
long GetUpperBound(long lDim).
The function ReDimArray calls ::SafeArrayReDim internally. Note that only the least significant dimension can be redimensioned. The parameters are respectively the lBound and cElements for the least significant dimension.
HRESULT ReDimArray(long lLBound, long lcElements)
The chunk of memory allocated for the array can be accessed using the member funtion
HRESULT AccessData(void HUGEP ** ppData), make sure to call the counter function after use to prevent unnecessary memory locking
HRESULT UnAccessData().
The encapsulated array member can be reteived using the function GetSafeArray
SAFEARRAY* pArr = NULL;
SafeArrObj.GetSafeArray(&pArr);
Hope this class saves a little time with safearrays.
Concern : Tested only with 2 dimensional arrays.. But should work for arrays of any dimension.
Comments
COleSafeArray::AccessData()
Posted by Legacy on 11/24/2002 12:00amOriginally posted by: RobertBrower
I want to display a data trace in MSChart. Instead of using COleSafeArray::PutElement() inside a nested for loop, is it possible to use AccessData() to get a pointer to the float data, then use memcpy to copy data from an array of float to the safe array? This would seem to make the charting routine go faster.
ReplyMFC COleSafeArray Port to ATL
Posted by Legacy on 02/17/2001 12:00amOriginally posted by: John Smith
MFC COleSafeArray Port to ATL
Can be foound at
http://www.sellsbrothers.com/tools/CComSafeArray.zip
By Ron Jacobs
great server example of out and incoming arrays
Client written is VB
Recommend downloading it
ReplyAdvantages over COleSafeArray
Posted by Legacy on 07/21/1999 12:00amOriginally posted by: TRP
I'm wondering, for MFC programmers, what are the advantages of this class over using COleSafeArray?
Reply