How to get the memory address of a VB (Visual Basic) variable
Problem: Sometimes the address of a variable is needed for calling a DLL function. But there is no documented built-in function or operator in VB to get the address of a variable.
Solution: The Win32 API function MulDiv can be used as a dummy function to get the address of a variable.
Note: The undocumented built-in functions VarPtr and StrPtr could also be used to get the address of a variable.
Private Declare Function GetAddrOf Lib "KERNEL32" Alias "MulDiv" (nNumber As Any, Optional ByVal nNumerator As Long = 1, Optional ByVal nDenominator As Long = 1) As Long ' This is the dummy function used to get the addres of a VB variable. Private Declare Sub MoveMemory Lib "KERNEL32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long) ' MoveMemory is used in HexDump to access arbitrary memory. ' This routine shows how to retrieve the address of a byte array. ' It dumps the contents of the array by passing its address to HexDump. Public Sub Test1() Dim A(8) As Byte: A(0) = &H55: A(1) = &HAA: A(2) = &H33 Dim Addr As Long: Addr = GetAddrOf(A(0)) HexDump Addr, 4 End Sub ' This routine shows how to coerce a string into a byte array and back into a string. Public Sub Test2() Dim A() As Byte A = "ABCabc" ' coerce Unicode string to byte array Dim Addr As Long: Addr = GetAddrOf(A(0)) HexDump Addr, UBound(A) + 1 A(4) = Asc("Z") ' change the third character to "Z" Dim S As String: S = A ' coerce byte array back to string Debug.Print "S=" & S End Sub ' This routine shows the difference between vbNullString and an empty string ("") ' and how to use "ByVal" when calling a DLL routine. Public Sub Test3() Debug.Print GetAddrOf(ByVal vbNullString) Debug.Print GetAddrOf(ByVal "") End Sub ' This routine dumps memory in hex. Public Sub HexDump(ByVal Addr As Long, ByVal Length As Long) Dim Offs: Offs = 0 Do While Offs < Length Dim L As Long: L = Length - Offs: If L > 16 Then L = 16 Dim A As Long: A = Addr + Offs Dim Buf(15) As Byte MoveMemory Buf(0), ByVal A, L Dim S As String: S = Hex(A) Dim SC As String: SC = "" Dim P As Long For P = 0 To L - 1 Dim b As Byte: b = Buf(P) S = S & IIf(P = 8, "-", " ") & IIf(b < 16, "0", "") & Hex(b) SC = SC & IIf(b >= 32 And b <= 127, Chr(b), ".") Next S = S & Space((16 - L) * 3) & " /" & SC & "/" Debug.Print S Offs = Offs + L Loop End Sub
Author: Christian d'Heureuse (www.source-code.biz, www.inventec.ch/chdh)
License: Free / LGPL