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

Tip of the Day
Language: VB4/32,VB5,VB6
Expertise: Advanced
Apr 20, 1999



Application Security Testing: An Integral Part of DevOps

The number of dimensions of an array

Using "pure" VB, the only way to build a generic routine that returns the number of dimensions of an array passed as an argument is using a loop that repeatedly tests the LBound (o UBound) function until it fails:

Function ArrayDims(arr As Variant) As Integer
    Dim i As Integer, bound As Long
    On Error Resume Next
    For i = 1 To 60
        bound = LBound(arr, i)
        If Err Then
            ArrayDims = i - 1
            Exit Function
        End If
End Function
You can write a faster routine by peeking at the memory location where Visual Basic holds the number of dimensions of any array:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As _
    Any, source As Any, ByVal bytes As Long)

Function ArrayDims(arr As Variant) As Integer
    Dim ptr As Long
    Dim VType As Integer
    Const VT_BYREF = &H4000&
    ' get the real VarType of the argument
    ' this is similar to VarType(), but returns also the VT_BYREF bit
    CopyMemory VType, arr, 2
    ' exit if not an array
    If (VType And vbArray) = 0 Then Exit Function
    ' get the address of the SAFEARRAY descriptor
    ' this is stored in the second half of the
    ' Variant parameter that has received the array
    CopyMemory ptr, ByVal VarPtr(arr) + 8, 4
    ' see whether the routine was passed a Variant
    ' that contains an array, rather than directly an array
    ' in the former case ptr already points to the SA structure.
    ' Thanks to Monte Hansen for this fix
    If (VType And VT_BYREF) Then
        ' ptr is a pointer to a pointer
        CopyMemory ptr, ByVal ptr, 4
    End If
    ' get the address of the SAFEARRAY structure
    ' this is stored in the descriptor
    ' get the first word of the SAFEARRAY structure
    ' which holds the number of dimensions
    ' ...but first check that saAddr is non-zero, otherwise
    ' this routine bombs when the array is uninitialized
    ' (Thanks to VB2TheMax aficionado Thomas Eyde for
    '  suggesting this edit to the original routine.)
    If ptr Then
        CopyMemory ArrayDims, ByVal ptr, 2
    End If
End Function
Francesco Balena
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