how do you dereference a variable pointer and get it's value back?

Seen many articles here on the use of varptr() to get the address of a variable, but how do you dereference it to get a variable's value from the address?
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

What type of variable are you getting the address of?
You can use rtlMoveMemory API (aka CopyMemory) to dereference a pointer:

Option Explicit

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

Private Sub Command1_Click()

    Dim lSource As Long
    Dim lDest As Long
    Dim lPointer As Long
    lSource = 101
    lPointer = VarPtr(lSource)
    'get the value from the pointer
    Call CopyMemory(lDest, ByVal lPointer, LenB(lSource))
    Debug.Print lDest

End Sub
keyboardsAuthor Commented:
So, at least as far as the above technique, you can't dereference the address to see what's there directly, but have to copy what's there to another location that is already of the correct type, yes?

Truthfully, I have dynamic arrays of user defined types, and I'd just like to be able to pass any of these arrays to a function.  But the arrays are not pre-declared, and have to be allocated at run-time.

Is there such a thing as a collection of arrays?  Or any other VB object type that would allow dynamic instantiation of at least a reference to something dynamically dimentioned?

I appreciate any advice, unless it's going to be "do it in C" *lol*; which I know would be a snap after porting.  Just can't screw myself up to the porting effort without exhausting all VB options. ;0}

Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

As long as you know the Type of the array, you can pass a dynamic array of user Types to a function.


Private Sub Command1_Click()

    Dim udtArray() As MyType
    Dim i As Long
    For i = 0 To 9
        ReDim Preserve udtArray(i)
        udtArray(i).member1 = i
        udtArray(i).member2 = i + 100
        udtArray(i).member3 = i + 1000
    Call PrintUDTArray(udtArray())
End Sub

Private Sub PrintUDTArray(udta() As MyType)
    Dim i As Long
    For i = 0 To UBound(udta)
        Debug.Print udta(i).member3
End Sub
keyboardsAuthor Commented:
you didn't pass it the address of the array.  I don't know what the name of the array will be at "compile time", it's dynamically allocated at run time.

I specifically need to know the syntax for obtaining, passing, and dereferencing the address of the array, without knowing it's name.
keyboardsAuthor Commented:
...and I guess I have to add "without copying the entire contents of the array passed to the function into another variable within the function". The dynamic arrays hold structures representing event absolute time, duration and magnatude and there might be a few million in a given array; this makes repeated copying prohibitive....unless we know the entire size of the array in memory and it's guarenteed contiguous and can be copied as a chunk relatively quickly and THEN dereferenced within the function.
You can grab any member of your array using CopyMemory without having to copy the entire array.  You will need a pointer to the array, plus the size of the member UDT in order to do this.

The array will always be contiguous in memory.


'Get the pointer to the array
Call PrintUDTArray( VarPtr( udtArray(0) ) )

'Pass in a pointer to the beginning of the array
Private Sub PrintUDTArray(ByVal UDTPtr As Long)
    Dim udt As MyType
    Dim offset As Long
    'Use CopyMemory to get the values of any member of the array
    'Get the 5th member of the array
    offset = LenB(udt) * 5
    'Copy the 5th member to a local variable
    Call CopyMemory(udt, ByVal (UDTPtr + offset), LenB(udt))
    Debug.Print udt.member1, udt.member2, udt.member3
End Sub


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Also be advised that CopyMemory does no bounds checking.  If you attempt to read or write to memory outside the heap, the program will crash and burn.  You must know that the pointer is valid and the extent of the array.

Save your work before running in the IDE.
keyboardsAuthor Commented:
Great stuff Erik, thanks for all the advice and code.  It shows me what the capabilities and limitations of VB are and that's it'll be quite a poor choice for this project, though it's done well enough for the slightly dumbed down draft version.

Imagine a mess of real-time events as input, each of a different, uncombinable type.  But you don't know what types there can possibly be or what event types you're going to get on any particular run, nor how many unique event types.  Similar types of events must be delt with along side each other but separate from other types, so you have to allocate an array for each type as it comes in, populate it,  and be able to find it again when another event of the same type is encountered from the input.  Thus I have to create a logical index of keys and addresses for dynamically allocated arrays for each event type I encounter from the input.  It may just seem like sorting from this superficial description, or that some presorting/prefiltering should have been done to the input; I'll just have to assure you it cannot.  And all event types cannot be in one array with an event_type property for reasons I cannot mention here.  And there is too much data to physically copy each time a new event type is encountered when there are potentially millions of events of each of the various kinds encountered at random distributions, and still meet performance requirements.

Lovely eh?  ;0}

Thanks again,
keyboardsAuthor Commented:
Got this link from another VB solution post here on EE.  Excellent article on casting variables through function aliasing.  That's the effect I was looking for, though the technique is somewhat surprising.

Don (aka Keyboards)
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.