Get Dynamic Array Information

Use the GetSafeArrayInfo function to rip the lid off a SAFEARRAY. It allows the caller to identify the number of dimensions and number of elements for each dimension (among other things). Element information for each dimension is stored in a one-based subarray of SAFEARRAYBOUND structures (rgsabound):

 Public Type SAFEARRAYBOUND	 ' # of elements in the array dimension	 cElements As Long	 ' lower bounds of the array dimension	 lLbound As LongEnd TypePublic Type SAFEARRAY	' Count of dimensions in this array.	cDims As Integer	' Flags used by the SafeArray	' routines documented below.	fFeatures As Integer	' Size of an element of the array.	' Does not include size of	' pointed-to data.	cbElements As Long	' Number of times the array has been	' locked without corresponding unlock.	cLocks As Long	' Pointer to the data.	' Should be sized to cDims:	pvData As Long	' One bound for each dimension.	rgsabound() As SAFEARRAYBOUNDEnd TypePrivate Declare Sub CopyMemory Lib "kernel32" Alias _	"RtlMoveMemory" (ByVal lpDest As Long, ByVal _	lpSource As Long, ByVal nBytes As Long)Public Function GetSafeArrayInfo(TheArray As _	Variant, ArrayInfo As SAFEARRAY) As Boolean'===================================================' Fills a SAFEARRAY structure for the array.' TheArray: The array to get information on.' ArrayInfo: The output SAFEARRAY structure.' RETURNS: True if the array is instantiated.'===================================================	' Pointer to the variants data item	Dim lpData		 As Long	' the VARTYPE member of the VARIANT structure	Dim VType		 As Integer	Const VT_BYREF	 As Long = &H4000&	' Exit if no array supplied	If Not IsArray(TheArray) Then Exit Function		With ArrayInfo		' Get the VARTYPE value from the first 2 bytes 		' of the VARIANT structure		CopyMemory ByVal VarPtr(VType), ByVal _			VarPtr(TheArray), 2				' Get the pointer to the array descriptor 		' (SAFEARRAY structure)		' NOTE: A Variant's descriptor, padding & 		' union take up 8 bytes.		CopyMemory ByVal VarPtr(lpData), ByVal _			(VarPtr(TheArray) + 8), 4		' Test if lpData is a pointer or a pointer to 		' a pointer.		If (VType And VT_BYREF) <> 0 Then			' Get real pointer to the array _descriptor 			' (SAFEARRAY structure)			CopyMemory ByVal VarPtr(lpData), _ByVal lpData, 4			' This will be zero if array not 			' dimensioned yet			If lpData = 0 Then Exit Function		End If		' Fill the SAFEARRAY structure with the array 		' info		' NOTE: The fixed part of the SAFEARRAY 		' structure is 16 bytes.		CopyMemory ByVal VarPtr(ArrayInfo.cDims), _			ByVal lpData, 16		' Ensure the array has been dimensioned before 		' getting SAFEARRAYBOUND information		If ArrayInfo.cDims > 0 Then			' Size the array to fit the # of _bounds			ReDim .rgsabound(1 To .cDims)			' Fill the SAFEARRAYBOUND structure with 			' the array info			CopyMemory ByVal VarPtr(.rgsabound(1)), _				ByVal lpData + 16, _				ArrayInfo.cDims _* Len(.rgsabound(1))			' So caller knows there is information 			' available for the array in output 			' SAFEARRAY			GetSafeArrayInfo = True		End If	End WithEnd Function
Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: