Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


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

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 Long
End Type
Public 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 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 _
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 With
End Function
Monte Hansen
 
Comment and Contribute

 

 

 

 

 


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

 

 

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