在VBA数据类型Array中,我们提到了取数组的函数,是使用1个API函数VarPtrArray ,要声明这么一个不大常用的API总觉得不大方便,我就在想能不能不需要API也可以获取到数组的地址呢?
在VBA指针Pointer里提到了3个取地址函数,VarPtr、StrPtr、ObjPtr。
其中提到了我们只需要VarPtr函数,是可以获取StrPtr、ObjPtr返回的地址的。
在VARANT里,我们讲到了Variant这个类型,它可以保存任何的类型,通过它的一个转换,我们不就可以获取到数组的地址吗?
是的,我们只要把1个数组赋值给1个Variant,然后去读取Variant里面的b8-11位,那获取的就是数组的地址或者是地址的地址了:
代码语言:javascript复制 - 0x20 8-11存的是数组地址
- 0x60 8-11存的是数组地址的地址
实现代码:
代码语言:javascript复制Sub TestMyArrayPtr()
Dim Arr() As Byte
ReDim Arr(3) As Byte
Dim ptr As Long '保存[Arr指针]的地址
CopyMemory VarPtr(ptr), VarPtrArray(Arr), 4
Printf "VarPtrArray(Arr) = 0x%x, ptr = 0x%x", VarPtrArray(Arr), ptr
Printf "MyArrayPtr(Arr) = 0x%x", MyArrayPtr(Arr)
End Sub
Function MyArrayPtr(ByRef v As Variant) As Long
Dim b(16 - 1) As Byte
CopyMemory VarPtr(b(0)), VarPtr(v), 16
Printf "b = 0x% x", b
Dim ptr As Long
CopyMemory VarPtr(ptr), VarPtr(b(8)), 4
' - 0x20 8-11存的是数组地址
' - 0x60 8-11存的是数组地址的地址
If b(1) = &H60 Then
CopyMemory VarPtr(ptr), ptr, 4
End If
MyArrayPtr = ptr
End Function
输出:
VarPtrArray(Arr) = 0x28eb90, ptr = 0x169d7cb0
b = 0x11 60 00 00 00 00 00 00 90 eb 28 00 00 00 00 00
MyArrayPtr(Arr) = 0x169d7cb0
这样一个简单的转换,我们就可以不需要API函数VarPtrArray 了。