In order to work with arrays created by other languages, such as VB arrays, PowerBASIC supports an extension of the pointer syntax, called "Pointer Indexing". As noted above, a pointer allows you access a data element at specific address in memory. An index pointer allows you to access data elements beyond the memory address in the base pointer. Consider an array with 6 elements:
DIM x%(0 TO 5)
The address of the first element, x%(0), is the base with the remaining elements stored in memory, one after the other. To access the array using an index pointer, you simply assign the address of the first element to your base pointer:
DIM xPtr AS INTEGER POINTER
xPtr = VARPTR(x%(0))
@xPtr[0] = 0 ' same as x%(0)
@xPtr[1] = 1 ' same as x%(1)
@xPtr[2] = 2 ' same as x%(2)
@xPtr[3] = 3 ' same as x%(3)
@xPtr[4] = 4 ' same as x%(4)
@xPtr[5] = 5 ' same as x%(5)
Note the syntax used to access the elements of the array. It consists of the pointer's name, with the @ prefix, and followed by the array index in square brackets. The number used inside of the brackets is a multiplier. The number inside the brackets is multiplied by the size of the target data (a two byte Integer in this case) to calculate the target address.
The primary differences between arrays and index pointers are than index pointers do not allocate any memory of their own - they use memory which has already been allocated elsewhere. Their lower bound is always zero. For example, you can dimension your six-element array from 1990 to 1995. However, to access the array data using an index pointer, you will still need to use 0 through 5:
x%(1990 TO 1995)
DIM xPtr AS INTEGER PTR
xPtr = VARPTR(x%(1990))
@xPtr[0] = 0 ' same as x%(1990)
@xPtr[1] = 1 ' same as x%(1991)
@xPtr[2] = 2 ' same as x%(1992)
@xPtr[3] = 3 ' same as x%(1993)
@xPtr[4] = 4 ' same as x%(1994)
@xPtr[5] = 5 ' same as x%(1995)
Consider the following VB code:
Sub Sum_Click()
ReDim PriceData!(1 TO TotalElements%)
Call FillSumArray(PriceData!())
Total! = GetSum(PriceData!(1), TotalElements%)
End Sub
When the "Sum" button is pressed, a dynamic array is created and filled. FillSumArray() is VB code to read the price data from a database file and place it into the array. GetSum() is PowerBASIC code to add up all of the prices and return the total, since PowerBASIC handles calculations faster than VB does.
FUNCTION GetSum!(Price!, BYVAL TotalElements%) EXPORT
DIM PriceData AS SINGLE PTR
DIM Total!
DIM k%
PriceData = VARPTR(Price!)
FOR k% = 0 TO TotalElements% - 1
Total! = Total! + @PriceData[k%]
NEXT
GetSum! = Total!
END FUNCTION
In the above example, GetSum! takes the Visual Basic array, adds
up all the values, and returns the total as a result. Since a pointer
is a memory address, we need the memory address of the first element in
the array. In VB, you can pass the memory address of a variable
by passing it "by reference", or
DECLARE FUNCTION GetSum! LIB "SUMS.DLL" (Prices!, BYVAL Elements%)
By not using the
Since only the first element of the array is passed to GetSum!, we'll need to use a pointer to access the remainder of the elements.
DIM PriceData AS SINGLE PTR
Remember that all pointers are initialized to null (zero). To access the array, we need to assign the memory address for the element passed. VARPTR is used to get the address of the passed element.
PriceData = VARPTR(Price!)
An indexed pointer can then be used to access all of the elements in the array. The VB array was dimensioned from 1 to TotalElements; however indexed pointers in PowerBASIC all start with a subscript of zero. So to reconcile the difference, we subtract the lower bound (1) from TotalElements in our FOR/NEXT loop. A DIM statement is not required to access an array using this method.
FOR k% = 0 TO Elems% - 1
Total! = Total! + @PriceData[k%]
NEXT
It is also possible to use indexed-pointers with dynamic string arrays. For example:
DIM Arr1(1 TO 3) AS STRING
DIM pArr1 AS STRING POINTER
Arr1(1) = "a1"
Arr1(2) = "a2"
Arr1(3) = "a3"
PArr1 = VARPTR(Arr1(1)) ' The 1st array element
DisplayText @pArr1[2] ' This references Arr1(3)
Indexed pointers make it easy to manipulate arrays created by other languages such as VB, Delphi, C/C++, etc.
See Also
Pointers to ASCIIZ and fixed-length strings
Pointers to arrays with dual indexes