gpt4 book ai didi

vba - 在 VBA 中使用 StrPtr 函数的好处和风险是什么?

转载 作者:行者123 更新时间:2023-12-04 07:18:00 30 4
gpt4 key购买 nike

在寻找一种方法来测试用户何时取消 InputBox ,我偶然发现了StrPtr功能。我相信它会检查一个变量是否曾经被赋值,如果它从未被赋值,则返回零,如果是,则返回一些神秘的数字。

好像是个有用的功能!我从这个代码开始:

Dim myVar as string
myVar = InputBox("Enter something.")
MsgBox StrPtr(myVar)

如果用户取消,消息框显示零。

极好的!但是为什么有些人坚持认为 StrPtr永远不会被使用?我读到它不受支持。为什么这很重要?

一个好的答案将解释使用 StrPtr 的好处(超出我上面的例子)和风险功能,可能是您如何使用(或不使用)它,而不给出是否每个人都应该使用它的意见。

最佳答案

tldr; 使用 StrPtr 没有真正的风险像那样,但也没有真正的好处。

虽然看起来你从 InputBox 得到了一个空指针。打电话,你实际上没有。比较StrPtr的结果至 VarPtr :

Sub Test()
Dim result As String
result = InputBox("Enter something.") 'Hit cancel
Debug.Print StrPtr(result) '0
Debug.Print VarPtr(result) 'Not 0.
End Sub

那是因为 InputBox正在返回 Variant子类型为 VT_BSTR .此代码演示(请注意,我已将 result 声明为 Variant,因此它不会被隐式转换 - 下面将详细介绍):
Sub OtherTest()
Dim result As Variant
result = InputBox("Enter something.") 'Hit cancel
Debug.Print StrPtr(result) '0
Debug.Print VarPtr(result) 'Not 0.
Debug.Print VarType(result) '8 (VT_BSTR)
Debug.Print TypeName(result) 'String
End Sub

原因 StrPtr返回0是因为 InputBox的返回值实际上是格式错误的(我认为这是实现中的错误)。一个 BSTR是一种自动化类型,它以字符串的长度作为实际字符数组的前缀。这避免了 C 风格的空终止字符串呈现自动化的一个问题——您要么必须将字符串的长度作为单独的参数传递,要么调用者不知道接收它的缓冲区有多大。 InputBox返回值的问题是 Variant它包含在数据区中包含一个空指针。通常,这将包含字符串指针 - 调用者将取消引用数据区中的指针,获取大小,为其创建缓冲区,然后读取长度 header 后面的 N 个字节。通过在数据区传递一个空指针, InputBox依赖调用代码来检查数据类型( VT_BSTR )实际上是 匹配 数据区中有什么( VT_EMPTYVT_NULL )。

检查结果为 StrPtr实际上是依赖于函数的那个​​怪癖。当它被调用时 Variant ,它返回指向存储在数据区中的底层字符串的指针,并通过长度前缀偏移自身以使其与需要 C 字符串的库函数兼容。这意味着 StrPtr必须对数据区域执行空指针检查,因为它没有返回指向实际数据开头的指针。此外,与在数据区中存储指针的任何其他 VARTYPE 一样,它必须取消引用两次。原因 VarPtr实际上给你一个内存地址是它给你一个原始指针,指向你传递给它的任何变量(数组除外,但这并不在这里真正的范围内)。

所以...这与使用 Len 真的没有什么不同. Len只返回 BSTR 的标题中的值(不,它根本不计算字符),并且出于类似的原因它也需要空测试 StrPtr做。它得出了空指针长度为零的逻辑结论 - 这是因为 vbNullstring 空指针:
Debug.Print StrPtr(vbNullString) '<-- 0

也就是说,您依赖于 InputBox 中的错误行为.如果微软要修复实现(他们不会),它会破坏你的代码(这就是他们不会的原因)。但总的来说,最好不要依赖这样的狡猾行为。除非您希望将点击“取消”的用户与不输入任何内容并点击“回车”的用户区别对待,否则使用 StrPtr(result) = 0 真的没有多大意义。赞成更清晰的 Len(result) = 0result = vbNullString .我断言,如果您需要做出这种区分,您应该将自己的 UserForm 放在一起。并在您自己的对话框中明确处理取消和数据验证。

关于vba - 在 VBA 中使用 StrPtr 函数的好处和风险是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42015700/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com