Pointer is a data type to declare variables as pointers.
Dim p As [Register] Pointer [To] type
Pointer p = addr%
addr% = Pointer(p)
p:pointer variable
type:any data type
addr%:memory address
The Pointer command and the Pointer() function apply to a variable of the Pointer [To] data type. A pointer variable can be declared for any type. The pointer variable then behaves as a variable of that type, but not before the pointer variable is assigned an address. Remember that each variable denotes a memory address of a specific size. An Integer variable holds the address of a 4 byte of memory block to store a value. In the same way, a pointer variable must be assigned a piece of memory to store the data type's value. The assignment of an address is done with the command Pointer p = addr%. The reverse, to get the address of memory pointer p points to, is done using the function addr% = Pointer(p).
In the next example a pointer to a Double data type is declared and assigned a memory location of 8 bytes in size. After the pointer assignment, the variable behaves like a Double. To check it, the variable is assigned the value 3.14, and then the memory location is peeked.
Dim addr% = mAlloc(8)
Local pdbl As Pointer Double
Pointer pdbl = addr%
pdbl = 3.14
Print DblPeek(addr%) // Prints 3.14
~mFree(addr%)
Pointers are more interesting used with user-defined types. In particularly, pointers are inevitable with API functions and messages that hand over pointers to structures (Type). For example, the WM_NOTIFY message used with notification messages from common controls specifies a pointer to the NMHDR type in the lParam parameter of the message. To get access to the type elements the address must be assigned to a variable of Pointer To NMHDR. The Example 1 shows how this is done.
Another use for pointers is for linked lists. A double linked list might use the following user-defined type:
Type LLIST
pNext As Pointer To LLIST
pPrev As Pointer To LLIST
value As Int
EndType
Global MyList As LLIST
Global pList As Pointer To LLIST
Pointer(pList) = V:MyList
The pNext and pPrev elements should be assigned memory addresses using Pointer pNext =.
Pointer(pList.pNext) = mAlloc(SizeOf(LLIST))
Pointer(pList.pPrev) = Pointer(pList)
Pointer(pList) = Pointer(pList.pNext)
pList.value = 2
Pointer arithmetic differs from C/C++, where the size of the type of the pointer is automatically included. In GFA-BASIC 32 incrementing a pointer involves adding the size of the type explicitly.
Pointer(p) = Pointer(p) + SizeOf(p) * 1
Example 1
Sub frm_MessageProc(hWnd%, Mess%, wParam%, lParam%, retval%, ValidRet?)
Dim hdr As Pointer NMHDR
Switch Mess
Case WM_NOTIFY
Pointer(hdr) = lParam
Print hdr.idfrom
EndSwitch
EndSub
Type NMHDR
hwndFrom As Long
idfrom As Long
code As Long
EndType
Example 2
Debug.Show
Local a$ = "12345", x%
Local aa As Pointer To Int
' Assign a memory location to the Integer:
Pointer aa = V:a$
Trace Pointer(aa)
Trace V:a$
Trace V:aa
'************
Trace aa
'************
Trace a$
' Change the contents of a$
aa = $41424344
Trace a$
' Add one to the pointer
Pointer aa = Pointer(aa) + 1
' change the contents from the second position
aa = $41424344
Trace a$
In GFA-BASIC 32 a user-defined variable may have the same name as the Type name. In VB or C/C++ this not allowed.
Note GFA-BASIC 32 provides s a double linked list with the Hash data type which can be used in place of linked lists.
{Created by Sjouke Hamstra; Last updated: 31/08/2022 by James Gaite}