Browse DevX
Sign up for e-mail newsletters from DevX

Tip of the Day
Language: Visual Basic
Expertise: Advanced
Oct 22, 2002



Building the Right Environment to Support AI, Machine Learning and Deep Learning

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):
	 ' # of elements in the array dimension
	 cElements As Long
	 ' lower bounds of the array dimension
	 lLbound As Long
End Type
	' 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 SAFEARRAYBOUND
End Type

Private 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 _
			' (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 _
			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 
			GetSafeArrayInfo = True
		End If
	End With
End Function
Monte Hansen
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date