专栏首页VBA 学习VBA指针Pointer

VBA指针Pointer

如果你想深入的了解VBA内部数据类型的内存布局,就必然需要知道变量所在的内存地址,VBA有3个取变量地址函数:

1、VarPtr

定义1个变量,函数返回这个变量的地址。

这个变量可以是任何类型(不能是数组)。

2、StrPtr

定义1个String类型

  • 初始化前,函数返回0,这个时候还没有字符的内存地址,所以是0
  • 初始化后,函数返回字符所在的内存地址(假设是ps)

与VarPtr得到的变量地址(假设是pv)关系是,pv这个地址保存的4个字节(32位电脑)的值就是ps。

Sub TestString()
    Dim str As String
    Dim lVarPtr As Long
        
    str = "a"
    CopyMemory VarPtr(lVarPtr), VarPtr(str), 4
    printf "VarPtr(str) = 0x%x, StrPtr(str) = 0x%x, lVarPtr = 0x%x", VarPtr(str), StrPtr(str), lVarPtr
End Sub
输出:
VarPtr(str) = 0x1ef030, StrPtr(str) = 0x17a455ec, lVarPtr = 0x17a455ec

说明:
API CopyMemory 声明
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)

printf 是自己封装的1个函数,代码没有列出

所以从上面可以看出,StrPtr就是把VarPtr得到的pv这个指针保存的内存数据读取出来。

也就是对String类型来说,其实有VarPtr就能够间接获取Str的字符所在地址,于是就想到尝试用StrPtr对数据类型的变量使用是不是也是一样的效果?

Sub TestStrPtr()
    Dim l As Long
    
    printf "VarPtr(l) = 0x%x, StrPtr(l) = 0x%x", VarPtr(l), StrPtr(l)
End Sub

输出:
VarPtr(l) = 0x1ef030, StrPtr(l) = 0x17a455ec

本以为在变量l未初始化也就是0的时候,StrPtr(l)应该返回0才对,为什么返回了一个值?这个如果也是个内存地址的话,里面又保存了什么?

Sub TestStrPtr()
    Dim l As Long
    
    printf "VarPtr(l) = 0x%x, StrPtr(l) = 0x%x", VarPtr(l), StrPtr(l)
      
    Dim b(3) As Byte
    CopyMemory VarPtr(b(0)), ByVal StrPtr(l), 4
    printf "b = 0x% x", b
End Sub

输出:
VarPtr(l) = 0x1ef030, StrPtr(l) = 0x118c6a5c
b = 0x30 00 00 00

输出的这个值还挺特殊!变量l赋值的话输出也会变化,不懂为什么!待研究……3、ObjPtr

这个和StrPtr好像差不多,VarPtr(obj)得到的地址po,po内存保存的数据等于ObjPtr(obj)

Sub TestObjPtr()
    Dim Rng As Range
    Dim lVarPtr As Long
    
    Set Rng = Range("A1")
    CopyMemory VarPtr(lVarPtr), VarPtr(Rng), 4
    printf "VarPtr(Rng) = 0x%x, ObjPtr(Rng) = 0x%x, lVarPtr = 0x%x", VarPtr(Rng), ObjPtr(Rng), lVarPtr
End Sub

输出:
VarPtr(Rng) = 0x1ef030, ObjPtr(Rng) = 0x8189280, lVarPtr = 0x8189280

本文分享自微信公众号 - VBA 学习(xyjvba),作者:熊业军

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

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

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

    xyj
  • VBA数据类型Variant

    官方文档定义:A special data type that can contain numeric, string, or date data as wel...

    xyj
  • 常用功能加载宏——筛选状态的单元格数值粘贴

    如果能有一个在筛选状态下也可以使用的数值粘贴功能就方便多了,让我们用VBA来实现它,效果:

    xyj
  • 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(13)-系统日志和异常的处理③

    上一节我们讲了如何捕获异常和记录日志,这一节我们讲,没有捕获的或者忘记捕获的异常包括404错误等,我们统一处理这个异常。 这一讲是利用 Application_...

    用户1149182
  • [Flutter Widget]Tooltip

    在前面的文章中我们讲到了Wrap的用法,介绍了Flutter中的流式布局,在文章的最后让大家实现如下效果:

    flyou
  • Vue中使用setTimeout()定时器延迟执行方法不生效的原因及解决

    直接使用上面的代码执行 closeModal() 方法会报错 Uncaught TypeError: this.showModal is not a funct...

    德顺
  • Javascript[0x02] -- 栈

    生活中栈的例子有很多,像子弹压膛然后发射、课代表把作业交给老师,总是最上面最迟交的那个人先挨批、搞计算机经常听到的内存堆栈溢出等等。

    丰臣正一
  • DC其他的时序约束选项(二)

    前面介绍的设计都不算很复杂,都是使用时钟的默认行为作为电路的约束,都存在有路径给你约束,即信号的变化要在一个时钟周期内完成,并达到稳定值,以满足寄存器的建立和保...

    数字芯片社区
  • numpy~运算符和Boolean类型变量

    DrawSky
  • 在自己的数据集上训练TensorFlow更快的R-CNN对象检测模型

    计算机视觉正在彻底改变医学成像。算法正在帮助医生识别可能错过的十分之一的癌症患者。甚至有早期迹象表明胸部扫描可有助于COVID-19的识别,这可能有助于确定哪些...

    代码医生工作室

扫码关注云+社区

领取腾讯云代金券