我在试验CopyMemory
时遇到了一个奇怪的问题。我有一段从 Bytecomb 复制的代码,只有当我把它放入一个函数中时才有效:
我把这个放在开头:
Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal ByteLen As Long)
工作版本:
Sub StringTest()
Dim str1 As String
Dim pstr1 As LongPtr
str1 = "PowerVB"
Debug.Print "Memory : 0x"; Mem_ReadHex(pstr1 - 4, LenB(str1) + 6)
End Sub
Public Function Mem_ReadHex(ByVal Ptr As LongPtr, ByVal Length As Long) As String
Dim bBuffer() As Byte, strBytes() As String, i As Long, ub As Long, b As Byte
ub = Length - 1
ReDim bBuffer(ub)
ReDim strBytes(ub)
CopyMemory bBuffer(0), ByVal Ptr, Length
For i = 0 To ub
b = bBuffer(i)
strBytes(i) = IIf(b < 16, "0", "") & Hex$(b)
Next
Mem_ReadHex = Join(strBytes, "")
End Function
该程序完美地打印出内存中字符串的整个布局(前 4 个字节表示长度,然后是字符串内容,然后是 2 个字节的 null(:
Memory : 0x0E00000050006F00770065007200560042000000
现在如果我将函数放入 sub 中,它会崩溃:
Sub StringTest()
Dim str1 As String
Dim str2 As String
Dim pstr1 As LongPtr
str1 = "PowerVB"
CopyMemory pstr1, ByVal VarPtr(str1), 8
Dim bBuffer() As Byte, strBytes() As String
ub = LenB(str1) + 5
ReDim bBuffer(ub)
ReDim strBytes(ub)
CopyMemory bBuffer(0), ByVal pstr1 - 4, LenB(str1) + 6 'extra 4 bytes for string length, and 2 bytes of null characters
For i = 0 To ub
b = bBuffer(i)
strBytes(i) = IIf(b < 16, "0", "") & Hex$(b) 'for 2 bytes, if the value < 16, then it only consists of one byte
Next i
Debug.Print Join(strBytes, "")
End Sub
我不明白。两个版本有什么区别?
好的,我找到了修复程序:
CopyMemory bBuffer(0), ByVal pstr1 - 4, ub + 1
因为 CopyMemory 必须将long
作为第三个参数,所以我不能使用LenB(str1) + 6
,因为它可能是一个整数。