VBA实现自己的ArrayPtr取数组地址函数

时间:2022-07-22
本文章向大家介绍VBA实现自己的ArrayPtr取数组地址函数,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

在VBA数据类型Array中,我们提到了取数组的函数,是使用1个API函数VarPtrArray ,要声明这么一个不大常用的API总觉得不大方便,我就在想能不能不需要API也可以获取到数组的地址呢?

VBA指针Pointer里提到了3个取地址函数,VarPtr、StrPtr、ObjPtr。

其中提到了我们只需要VarPtr函数,是可以获取StrPtr、ObjPtr返回的地址的。

在VARANT里,我们讲到了Variant这个类型,它可以保存任何的类型,通过它的一个转换,我们不就可以获取到数组的地址吗?

是的,我们只要把1个数组赋值给1个Variant,然后去读取Variant里面的b8-11位,那获取的就是数组的地址或者是地址的地址了:

    - 0x20 8-11存的是数组地址
    - 0x60 8-11存的是数组地址的地址

实现代码:

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 了。