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.
Examples:
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
No comments:
Post a Comment