No announcement yet.

Array descriptor address (PB9)

  • Filter
  • Time
  • Show
Clear All
new posts

  • Array descriptor address (PB9)

    In 2005, Eric Cochran posted a thread called Yes, You CAN Redim Arrays Via A Ptr To Their Descriptor... in the source code forum.

    A reply to the initial message implied that this could be a mistake.

    However, in the PB8 and PB9 help, it states:
    VARPTR may also be used to locate an array descriptor, as well as the array data itself. To find the address of an array descriptor, use the array name with empty parentheses: VARPTR( x( ) ).
    REDIM - Restrictions
    When a REDIM statement is executed, the location of the array elements always moves in memory; however, the array's Descriptor location (VARPTR(arrayname()) will remain fixed at the original location.
    I have found this to be a useful technique (i.e. passing array data and meta-data to generic forms) and have had no problems using this. However, I am interested if anyone else has found related issues.

    To obtain the array descriptor address, use the following syntax as per the help text:
        'Local hPtr As <type> Ptr
        'hPtr = VarPtr(MyArray())
        ' e.g.
        Local MyArray() As String
        Local hPtr As String Ptr
        ReDim MyArray(5)
        hPtr = VarPtr(MyArray())
    Here is a sample of its use, using a string array. It works with other data types, including UDT's.

    ' test array descriptor address. Compiler: PB9
    #Compile Exe
    #Dim All
    Function TestStr(aData() As String) As Long
    ' test string array descriptor
    ' aData(): parameter is ByRef, but pass array address descriptor value as ByVal
    ' return:  upper bound of array
    ' e.g.:    Call TestStr(aStrData())      passed array ByRef
    ' or:      Call TestStr(ByVal hStrPtr)   passed address of array descriptor
    '                                        for array ByVal
        Local lUB As Long
        lUB = UBound(aData)
        ReDim Preserve aData(lUB + 2)
        aData(lUB + 1) = "apple"
        aData(lUB + 2) = "orange"
        Function = UBound(aData)
    End Function
    Function PbMain()
        Local aStrData() As String
        Local hStrPtr As String Ptr
        ReDim aStrData(4)
        Array Assign aStrData() = "cat", "dog", "rat", "bat", "eel"
        ? "1. Upper bound of string array is: " + Str$(UBound(aStrData)) + $crlf + _
            "with value: " + aStrData(UBound(aStrData)) + $crlf + _
            "elements: " + Str$(ArrayAttr(aStrData(), 4))
        hStrPtr = VarPtr(aStrData())
        Call TestStr(ByVal hStrPtr)         ' same as: Call TestStr(aStrData())
        ? "2. Upper bound of string array is: " + Str$(UBound(aStrData)) + $crlf + _
            "with value: " + aStrData(UBound(aStrData)) + $crlf + _
            "elements: " + Str$(ArrayAttr(aStrData(), 4))
    End Function
    Other references include:
    A Technique For Using Dynamic Arrays In UDTs

    storing dynamic arrays inside a UDT


  • #2
    FUNCTION RedimMyArray (Z() AS anthing, newubound AS LONG) AS LONG
      REDIM  Z(newUbound) 
    .... is redimming an array via a pointer to its descriptor, too.

    It basically HAS to work. It's also the basis for....
    Single Function to process any array type (CC3/Win7+) 12-17-03

    There's only one way it WON'T work, and that should not occur unless you are using a mixture of PB/DLL 5/6x with PB/Win 7+ AND you are passing a UDT array.
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]