Pointers in VBA. (1 Viewer)

Status
Not open for further replies.

ChrisO

Registered User.
Local time
Today, 21:07
Joined
Apr 30, 2003
Messages
3,202
Pointers in VBA.

Don’t get nervous, you use them all the time.

What is a Pointer? The answer needs some explanation.

Objects, such as Text Boxes, List Boxes, Recordsets, Forms etcetera, are much too large to go passing around an application efficiently. An example would be a Recordset which could be 500 MByte in size. We don’t want to move or copy such a large Object from A to B in memory just to ‘get at it’ at B. So we leave the Object where it is and just pass the memory address of the Object instead.

Over the years there has been an analogy to this. If we send a message to someone, through the mail, we can include a return street address to our house. We put the return street address of our house in the message not the house itself; makes it easier for the postman to carry it about. Similarly, when we pass an Object, we pass the memory address of that Object and not the Object itself.

But the memory address of an Object is still not a Pointer, it is the value held in that Pointer. In other words, the memory address of an Object is that which a Pointer contains. It is important to understand the difference between a Pointer and the content of a Pointer.

To explain this a little further we need some VBA code:-

Dim X As Object

What does that line of code mean?
From Access help…

Dim: Declares variables and allocates storage space.
X: The name of the storage space allocated.
Object: A data type that represents any Object reference. Object variables are stored as 32-bit (4-byte) addresses that refer to objects.

Let’s have a closer look at these…
X is the name of the storage space allocated but it does not specify the size of the storage space allocated.
Object specifies the size of the storage space allocated, which is 4 bytes for a memory address in a 32 bit system. That definition applies to all Objects in a 32 bit system. Objects vary in size but their address size remains the same…4 bytes.

Note then that the real line of code:-
Dim X As Object
Could just as well have been written as:-
Dim X As ObjectPointer
Or more simply as in:-
Dim X As Pointer

But Microsoft seems to have decided on the word Object and we need to go with that.
(However, the word Object is wrong and ObjectPointer, or just plain Pointer, would have been a better choice. :D )

But we must be clear here; X it is not an Object, Objects vary in size.
X is the name of a Pointer and that Pointer was allocated a fixed memory size, 4-bytes.

Note also that there is something else going on in the real line of code:-
Dim X As Object
The content of X is actually initialized to 0. The content of X is actually a Long 4-byte numerical value. All numerical values are initialized and reset to 0. The content of X is the address of an Object. The initial value of X is the address of a special Object called Nothing. We actually de-allocate a Pointer by setting its value to the Object Nothing and the memory address of that special Object Nothing is 0.

We can come back to that if need be; let’s just push on for the moment…

Dim X As Object
X is the name of a 4-byte contiguous storage allocation in memory.
Those 4-bytes contain the numerical value of an Object’s address.
Juxtaposition
Dim Y As Long
Y is the name of a 4-byte contiguous storage allocation in memory.
Those 4-bytes can contain the numerical value of any Object’s address.

How do we transfer the numerical value of a Pointer X (address of the Object) to the value of a Long Y?
How do we transfer the value of a Long Y back to the numerical value of a Pointer X (address of the Object) ?

Simple and fast…
Code:
Option Explicit
Option Compare Text

[color=green]' API and constants from http://allapi.mentalis.org/apilist/apilist.php[/color]
Private Const POINTERSIZE As Long = 4
Private Const ZEROPOINTER As Long = 0

Private Declare Sub RtlMoveMemory Lib "kernel32" (ByRef Destination As Any, _
                                                  ByRef Source As Any, _
                                                  ByVal Length As Long)


Public Function GetPointerToObject(ByRef objThisObject As Object) As Long
    [color=green]' Purpose  : Return the value of a pointer.
    ' Argument : A pointer to an Object.[/color]
    
    Dim lngThisPointer As Long

    RtlMoveMemory lngThisPointer, objThisObject, POINTERSIZE
    GetPointerToObject = lngThisPointer

End Function


Public Function GetObjectFromPointer(ByVal lngThisPointer As Long) As Object
    [color=green]' Purpose  : Return a pointer to an Object.
    ' Argument : The value of a Pointer.[/color]
    
    Dim objThisObject As Object

    RtlMoveMemory objThisObject, lngThisPointer, POINTERSIZE
    Set GetObjectFromPointer = objThisObject
    RtlMoveMemory objThisObject, ZEROPOINTER, POINTERSIZE

End Function
Note here that the API call is bidirectional, low level, fast and documented.
It copies the content of one named variable to the content of another named variable.


Next, how can we use it?

The passing of Objects, which are really Object Pointers, can not be done through OpenArgs. However, OpenArgs uses the Variant data type and the Variant datatype supports the Long data type.

The method is, therefore…
Value of Object Pointer > value of Long > through OpenArgs > value of long > value of Object Pointer.

Note here as well…
This is a straight passing of an Object (Opject pointer) through OpenArgs by reference (ByRef).
Any modification done, via the received Pointer, will take effect immediately on the Object. Therefore there is no need to pass anything back to the caller.

The Pointer may point to a Collection which, in turn, contains other Pointers.

Some sample usage demonstrations are available in the link in my signature.

I have attached perhaps the simplest demo of this technique.
It passes the value of pointer to a Text box to another Form which allows direct write back to the caller.

It is possible to pass Objects (Object Pointers) through OpenArgs, imagination is the limit.

Have fun experimenting,
Chris.
 

Attachments

  • TextBox_PassObject_A2003.zip
    19.2 KB · Views: 1,623
Last edited:
Status
Not open for further replies.

Users who are viewing this thread

Top Bottom