VarPtr 得到地址 指针
在Basic语言演变成QBasic,然后到Visual Basic之前,VarPtr函数就已经存在了。开始,这个函数存在于VB运行库1.0版中。通过声明可以调用这个函数:
Declare Function VarPtr Lib "vbrun100.dll" (Var As Any) As Long
数年之后,vbrun100.dll变成了msvbvm50.dll,但该函数的入口点却还在那儿。为了获取变量的地址,只须将变量名传递给该函数就行了。例如:
Dim l As Long
Debug.Print VarPtr(l)
类似地,为了获取字符串的指针,而非保存字符串的变量的指针,只须在变量名前加上ByVal即可。如:
Debug.Print VarPtr(s),VarPtr(ByVal s)
在VB3之前,用这种方法来获取字符串缓冲的指针是非常普遍的。但在VB4却遇到了一点麻烦。
ANSI/UNIDCODE问题
随着32位世界和VB4的到来,我们迈进了一半是UNICODE,一半是ANSI的Windows世界。而在此之前,是ANSI一统天下。在VB中,所有字符串按UNICODE保存,但所有的API调用却仍使用ANSI字符串。这就要求在调用API函数之前,将字符串从UNICODE转换成ANSI,函数执行结束后,将返回的字符串从ANSI转换成UNICODE。虽然大多数时候这种转换对用户来说是透明的,但这就使利我们不能将一个字符串类型的参数以UNICODE方式从VB传递给DLL。类似地,任何包含有字符串的结构在执行API调用时,也必须经过这种双重转换。
这种差异是如何影响VarPtr函数的呢?当一个字符串传递给VarPtr函数时,函数执行后所返回的地址是保存临时ANSI字符串的临时ANSI字符串或变量的地址。换句话说,这个地址并不是你声明的变量的真正地址。因此,对于字符串变量以及包括字符串的结构来讲,这个函数一点用也没有。
VB5来解决问题
为了能VarPtr能重新发挥作用,VB5(及Office97)加入了三个针对VBA类型库的入口点。这些入口点为VarPtr函数提供了内置的声明。这三个函数的作用是:
VarPtr:返回变量地址
StrPtr:返回真正的UNICODE字符串缓冲区的地址
ObjPtr:返回任何对象变量引用的地址
VarPtr其函数原型如下,用OleView打开c:\windows\system32\msvbvm60.dll可知:
[entry(0x60000006), hidden]
long _stdcall VarPtr([in] void* Ptr);
请看下两个例子:
例一:
Dim s As Long:s=-11 ‘为非指针型变量均可,如Byte等,会转化成Long。
MsgBox VarPtr(s) ‘得到变量s的地址
MsgBox VarPtr(-11) ‘得到临时变量的地址
MsgBox VarPtr(ByVal s) ‘不用建立临时变量,结果为-11。如果VarPtr为取址,肯定不会为-11;此处不取址了,仅转化值。
例二:
Dim s As string:s=”asdfg”
MsgBox VarPtr(s) ‘得到变量s的地址
MsgBox VarPtr(“asdfg”) ‘得到临时变量的地址
MsgBox VarPtr(ByVal s) ‘得到字符串”asdfg”的地址
上面两例的结果均为Long型,且前两个地址数值相近,因均属变量型,而最后一个为常量。
VB不鼓励使用指针,比如MsgBox s,单独用变量名s,就是无法得地址。VarPtr的最大作用,当然是突破限制、“抠”出了变量的指针数值。那“数值转化”有什么用呢?其实没什么特别。我们来自己定义个VarPtr,在例一中加上Private Declare Function VarPtr Lib "msvbvm60.dll" (x As Any) As Integer,会进行Long与Integer的转换。
再看例三,三个MsgBox的结果相同:
例三:
Dim s As Long:s = -11
MsgBox VarPtr(s)
MsgBox VarPtr(ByVal VarPtr(s)) ‘不可省去ByVal,那会是临时变量的地址
Dim t As Long
t = VarPtr(s)
MsgBox VarPtr(ByVal t)
End
可以看出,实参中ByVal VarPtr(x)的搭配和(ByRef) x一样;VarPtr(ByVal x)和x一样。
VarPtr 得到地址 指针的更多相关文章
- JS数组的concat、push等方法,操作的是地址指针,而非内存操作
var a = [{x:1}, {y:1}, {z:3}]; var b = a.concat(['gg', 'ff']); var c = []; c.push(a[1]); console.log ...
- 【嵌入式开发】C语言 内存分配 地址 指针 数组 参数 实例解析
. Android源码看的鸭梨大啊, 补一下C语言基础 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/detai ...
- C语言 内存分配 地址 指针 数组 参数 实例解析
. Android源码看的鸭梨大啊, 补一下C语言基础 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/detai ...
- C语言 数组名不是首地址指针
今天上计算机系统课的时候老师讲到了C中的聚合类型的数据结构.在解释数组名的时候说"数组名是一个指针,指向该数组的第一个元素",附上ppt(第二行): 我觉得这是不正确的,是一个常见 ...
- 终于懂了:Delphi的函数名不是地址,取地址必须遵守Object Pascal的语法(Delphi和C的类比:指针、字符串、函数指针、内存分配等)good
这点是与C语言不一样的地方,以前我一直都没有明白这一点,所以总是不明白:函数地址再取地址算怎么回事? ------------------------------------------------- ...
- 获取VB类模块成员函数指针(转)
最近在做一些VB6.VBA的项目,被如何获取类模块中的函数指针这个问题所困扰,收集整理后,有2分资料值得收藏,特将关键部分留存,以备后续查找. 参照连接1:http://www.cnblogs.com ...
- c/c++ 函数、常量、指针和数组的关系梳理
压力才有动力,15年中旬就要准备实习,学习复习学习复习学习复习学习复习……无限循环中,好记性不如烂笔头……从数组开始,为主干. c 的array由一系列的类型相同的元素构成,数组声明包括数组元素个数和 ...
- 几年前做家教写的C教程(之四专讲了指针与汉诺塔问题)
C语言学习宝典(4) 指针:可以有效的表示复杂的数据结构,能动态的分配动态空间,方便的使用字符串,有效的使用数组,能直接处理内存单元 不掌握指针就没有掌握C语言的精华 地址:系统为每一个变量分配一个内 ...
- C语言回顾-指针
1.指针:地址 指针变量:存放指针的变量 指针变量的定义:数据类型 *指针变量名 或者 数据类型* 指针变量名 指针变量的初始化:int *p=&a;int *p=NULL;(不能先定义后初始 ...
随机推荐
- Linux终端(Xshell等)的编码设置
先简单说说一下遇到的情况吧: 在用类似Xshell的工具连接远端Linux时,运行命令ls时,如果有中文,就会显示有乱码: 网上查资料时,也把相应的连接属性修改为utf-8了(见下图),但是还是不行: ...
- Android MMC/EMMC/MTD Partition Layout
Android devices have a couple of partitions to store different data. The common ones are the recover ...
- LoadRunner的简单使用《第一篇》
LoadRunner是一个用压力测试的软件.这东西比较难上手,光安装就非常麻烦.好不容易一步步跟着安装说明安装好之后,还是用不了. 记录一个问题如下: 导入脚本的时候报错fail to create ...
- Oracle 12c on Solaris 10 安装文档
http://www.orasql.com/blog/archives/2013/08/20/12c_solaris.htm
- 更改mysql字段的编码类型为utf8mb4
ALTER TABLE tb_case MODIFY COLUMN content VARCHAR(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode ...
- Spring加载Hibernate 映射的几种方式及区别
LocalSessionFactoryBean有好几个属性用来查找hibernate映射文件: mappingResources.mappingLocations.mappingDirectoryLo ...
- [runtime] initialize方法讲解
+ (void)initializeDescription(描述) Initializes the class before it receives its first message. 在这个 ...
- [GIt] 团队工作效率分析工具gitstats
copy : http://www.cnblogs.com/ToDoToTry/p/4311637.html 如果你是团队领导,关心团队的开发效率和工作激情:如果你是开源软件开发者,维护者某个repo ...
- 第六章 字节码执行方式--解释执行和JIT
注:主要参考自<分布式java应用:基础与实践><深入理解Java虚拟机(第二版)> 1.两种执行方式: 解释执行(运行期解释字节码并执行) 强制使用该模式:-Xint 编译为 ...
- 如何将thick provision lazy zeroed的VMDK文件转换为thick provision eager zeroed?
详细步骤在此: Enabling clustering features for an existing virtual disk by converting in place(1035823) ht ...