Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.

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