VarPtr、StrPtr和ObjPtr函数的用法

VB6程序中验证ByREF, ByVal, VarPtr, StrPtr, Poke, Peek, DBCS, SBCS, Ansi, Unicode的区别与使用 字符串存储格式影响着编程使用,C格式字符串是以 \0 作为结束符,其长度可以由此计算,而VB格式的字符串其长度存于字符串前缀之中。不仅如此,字符串编码方式 ansi, unicode, widestring, dbcs, sbcs 这些概念也影响着长度计算。笔记用VB6程序对它们进行剖析验证。 阅读详情
  在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:返回任何对象变量引用的地址

下面是这三个函数的具体用法。

StrPtr

该函数主要用来产生高效的UNICODE API调用。在VB4,UNICODE形式的API函数的调用必须借助于Byte数组,例如:

Declare Sub MyUnicodeCall Lib "MyUnicodeDll.dll" (pStr as Byte)

Sub MakeCall (MyStr as String)

Dim BTmp() as Byte
bTmp=MyStr & vbNullChar
MyUnicodeCall bTmp(0)
MyStr=bTmp
MyStr=left(MyStr, Len(MyStr)-1)

End Sub

如果使用StrPtr,上面的代码精简为:

Declare Sub MyUnicodeCall Lib "MyUnicodeDll.dll" (pStr as Byte)

Sub MakeCall (MyStr as String)

MyUnicodeCall StrPtr(MyStr)

End Sub

VarPtr/StrPtr/ObjPtr的执行速度非常非常快,因此调用UNICODE函数所赞成有系统负担实际上小于调用相对应的ANSI函数。因为前者不需进行转换。

StrPtr还能用于优化ANSI API函数的调用。在调用时使用StrConv和StrPtr就能避免将一个字符串变量多资传递给函数以及为每个调用而执行转换操作所造成的系统负担。例如原来的:

Declare Sub MyAnsiCall Lib "MyAnsiDll.dll" (ByVal pStr As String)

MyAnsiCall MyStr

现在变为:

Declare Sub MyAnsiCall Lib "MyAnsiDll.dll" (ByVal pStr As Long)

MyStr=StrConv(MyStr,vbFromUnicode)
MyAnsiCall StrPtr(MyStr)
MyStr=StrConv(MyStr,vbUnicode) '并不总是要求

StrPtr还是唯一能直观地告诉你空字符串和null字符串的不同的方法。对于null字符串(vbNullString),StrPtr的返回值为0,而对于空字符串,函数的返回值为非零。

VarPtr

该函数能与要求包含有UNICODE字符串的结构的API调用一起使用。如果将一个MyUDTVariable变量(一个自定义类型的变量)传递给一个由ByRef UDTParam As MyUDT定义的参数,就会发生ANSI/UNICODE之间的转换。但是,如果将VarPtr(MyUDTVariable)传递给由ByVal UDTParam As Long定义的参数,则不会发生这样的转换。

有一点需要特别注意,在VB中指针的算法非常重要。此外,你必须计算元素的大小,因为VB不会帮你完成这项工作。你还必须处理缺乏无符号长整型数据类型的问题。下面的函数实现了无符号算法

Function UnsingedAdd (ByVal Start As Long, ByVal Incr As Long) As Long

Const SignBit As Long = &H80000000
UnsignedAdd=(Start Xor SignBit) + Incr Xor SignBit

End Function

 

该函数返回由对象变量引用的接口指针。由于大多数对象都支持多重接口,因此搞清楚地址对应的是对象的哪一个接口就非常重要了。通常个函数用来放在集合中的对象。通过创建基于对象地址的关键字,你就可以在不需要启遍历整个集合中所有元素的情况下,轻松地将对象从集合中删除。在许多情况下,对象地址是唯一可靠的能作为关键字的东西,示例如下:

ObjCol.Add MyObj1,CStr(ObjPtr(MyObj1))

.....

ObjCol.Remove CStr(ObjPtr(MyObj1))

vb实现多线程! 昨晚2:30的时候还没睡着,觉得有必要把vb编写多线程程序再次写一次;主要是以前忽略的细节和重要的环节;今天在公司打开一年多没用的vb,写了如下的代码;想写多线程的朋友可以调试一下看看,关于多线程的任务模式,同步和互斥,临界资源和临界区(文中提到)欢迎跟帖讨论; 请将该部分数据保存为 FORM1.frm 文件 VERSION 5.00 Begin VB.Form Form1   Caption  阅读详情

相关推荐

StrPtr

返回字符串的当前内存地址。

李家小院 48

VarPtr函数

发展历史在Basic语言演变成QBasic,然后到Visual Basic之前,VarPtr函数就已经存在了。开始,这个函数存在于VB运行库1.0版中。通过声明可以调用这个函数:Declare Function VarPtr Lib "vbrun100.dll" (Var As Any) As Long数年之后,vbrun100.dll变成了msvbvm50.dll,但该函数的入口点却还在那儿。为

njstalk的专栏 2897

精彩编程与编程技巧-VarPtr、StrPtr和ObjPtr函数的用法...

VarPtr、StrPtr和ObjPtr函数的用法

VB中的指针与指针变量

vb指针是什么:   指针的概念源于C语言,VB没有指针的概念,但其实对象变量就可以看成是指针: Set A=Obj 'A就是指向Obj的地址'   VB中的指针实际就是某一变量的内存地址。例如下面的p储存了a的内存地址: dim a as long dim p as long p=VarPtr(a)   上网查资料也有的说vb指针是有的,只不过被隐藏起来了,因为vb官方不鼓励用户使用指针。...

devops 3420

LCD驱动芯片——BL55072A驱动程序

初始化子程序: START 0x7C; I2C子地址 0xEA;ICSET,软件复位芯片 0xC0;MODSET,关显示 0xF0;BLKCTL,关闪烁 0xA3;DISCTL,80Hz Line inversion,High Power mode 0xE8;ICSET,清复位bit1 STOP 显示刷新子程序: START 0x7C;I2C子地址 0xF0;BLKCTL,关闪烁 0xA3;DISCTL,80Hz Line inversion,High Power mode 0xE8或0xEC;ICSE

love421的博客 3175

RAG在医药行业为什么80%都翻车了?

这篇文章不是要劝你别做RAG,而是把坑说清楚。医药行业有它的特殊性——监管压力、专业术语密度、多语言混排、文档结构复杂——这些因素叠加在一起,让标准RAG教程里的那套方法论几乎直接失效

qq_31808385的博客 635

VarPtr 得到地址 指针

在Basic语言演变成QBasic,然后到Visual Basic之前,VarPtr函数就已经存在了。开始,这个函数存在于VB运行库1.0版中。通过声明可以调用这个函数: Declare Function VarPtr Lib "vbrun100.dll" (Var As Any) As Long 数年之后,vbrun100.dll变成了msvbvm50.dll,但该函数的入口...

demonzsmj12315的博客 313

【QGIS】PyCharm集成pyqgis的processing工具箱:环境配置与初始化实战

本文详细介绍了如何在PyCharm中配置QGIS的Python环境并成功集成其强大的Processing工具箱。文章核心解决了独立环境下导入processing模块失败、算法无法调用等常见难题,通过手动添加插件路径和执行关键初始化步骤,实现了在PyCharm中丝滑调用QGIS地理处理算法,从而将复杂的空间分析流程自动化。

weixin_28831399的博客 390

如何在Visual Basic 中取得变量在内存中的地址(Address of Variables)

如何在Visual Basic 中取得变量的内存地址(Address of Variables)本文适用于Microsoft Visual Basic Learning Edition for Windows, versions 5.0, 6.0 Microsoft Visual Basic Professional Edition for Windows, versions 5.0, 6.0

软件开发资料汇总 379

【Android14 ShellTransitions】Transition就绪:双Transaction与SurfaceControl显示时机剖析

本文深入剖析了Android14 ShellTransitions框架中Transition就绪阶段的核心机制。重点解释了为何需要“双Transaction”来精确控制SurfaceControl的显示与隐藏时机,以确保Activity切换动画的流畅性。通过分析onTransactionReady流程、窗口绘制状态机及动画目标提升策略,揭示了系统如何协调WMCore与WMShell,实现从状态收集到动画播放的无缝衔接。

ooo22的博客 526

ResNet改进(7):添加 SK注意力机制

实现 SK 注意力机制。

2401_82355416的博客 730

VB中利用CopyMemory使用指针

一、指针是什么?   不需要去找什么标准的定义,它就是一个32位整数,在C语言和在VB里都可以用Long类型来表示。在32位Windows平台下它和普通的32位长整型数没有什么不同,只不过它的值是一个内存地址,正是因为这个整数象针一样指向一个内存地址,所以就有了指针的概念。   有统计表明,很大一部分程序缺陷和内存的错误访问有关。正是因为指针直接和内存打交道,所以指针一直以来被看成一个危险的东西。...

miaozk2006的专栏 335

全覆盖路径规划开源项目Clean-robot-turtlebot3关键函数解析(上)

本系列文章主要介绍全覆盖路径规划开源项目Clean-robot-turtlebot3的相关内容,包含如下四篇文章,分别介绍了开源项目Clean-robot-turtlebot3流程的概括总结、ROS坐标系常用坐标及其变换、Clean-robot-turtlebot3关键函数解析等内容。

慕羽★的博客 2778

深入了解VB中的变量和指针(一)

前言:我们都知道,在VB中,可以使用VarPtr、StrPtr和ObjPtr来获得变量的地址,它们之间有什么区别和联系呢?许多资深的VB人员告诉我们,最好将API函数声明中ByVal lpstr As String改为ByVal lpStr As Long,这又是为什么呢?如何正确地利用这些函数向API传递指针呢?    首先,我们来了解一下VB中的变量及其定义。    也许你会说我多此一

lyserver的专栏 3549

基于深度学习的柠檬等级检测系统 —— YOLOv8 + UI界面 + 数据集

本项目的目标是构建一个柠檬等级检测系统,通过深度学习模型自动检测柠檬的等级。自动检测柠檬等级:通过图像中的柠檬特征,自动判断其成熟度和质量。实时视频检测:通过摄像头实时监控柠檬的质量等级。用户友好的UI界面:为用户提供简洁直观的操作界面,支持图像上传、实时视频检测等功能。本项目展示了如何基于YOLOv8模型开发一个柠檬等级检测系统,结合PyQt5实现了用户友好的UI界面。通过该系统,用户可以快速上传柠檬图像并自动识别其等级,极大提升了检测效率和准确性。数据集的扩展。

YOLO 1111

YOLOv12改进策略【Neck】| 使用CARAFE轻量级通用上采样算子

CARAFE内容感知的特征重新组合。

Limiiiing的博客 664

vb6 webclass是做什么的_VB6 / VBA 的秘密

本文是从我个人博客上搬过来的。翻译于去年(2018)。原博客文章将会删除。本文主要讲的是VB中的指针,是我看过的讲得最好的一篇文章。很底层的东西,有兴趣的可以看看,对学习Windows API编程很有帮助。若翻译有欠妥的地方,欢迎指正。原文网址:http://www.thevbzone.com/secrets.htm作者:Kevin Wilson目录:介绍在Visual Basic 中使用指针Va...

weixin_39888049的博客 379

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

VB的使用

一、今天讲解VB的vb.net教程使用,明天讲解VC与VB的相互调用: 1.指针是什么? 不需要去找什么标准的定义,它就是c#教程一个32位整数,在C语言和在VB里都可以用Long类型来表示。在32位Windows平台下它和普通的python基础教程32位长整型数没有什么不同,只不过它 的值是一个内存地址,正是因为这个整数象针一样指向一个内存地址,所以就有了指针的概念。 有统计表明,很大一部分程序缺陷和内java基础教程存的错误访问有关。正是因为指针直接和内存打交道,所以指针一直以...

chinaherolts2008的博客 1759

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

上一篇: VB用copymemory快速交换两个字符串
下一篇: 小技巧:ListView如何按数字大小排序
wjb9921
博客等级 码龄23年 24粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值