作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在寻找一种方法来测试用户何时取消 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_EMPTY
或
VT_NULL
)。
StrPtr
实际上是依赖于函数的那个怪癖。当它被调用时
Variant
,它返回指向存储在数据区中的底层字符串的指针,并通过长度前缀偏移自身以使其与需要 C 字符串的库函数兼容。这意味着
StrPtr
必须对数据区域执行空指针检查,因为它没有返回指向实际数据开头的指针。此外,与在数据区中存储指针的任何其他 VARTYPE 一样,它必须取消引用两次。原因
VarPtr
实际上给你一个内存地址是它给你一个原始指针,指向你传递给它的任何变量(数组除外,但这并不在这里真正的范围内)。
Len
真的没有什么不同.
Len
只返回
BSTR
的标题中的值(不,它根本不计算字符),并且出于类似的原因它也需要空测试
StrPtr
做。它得出了空指针长度为零的逻辑结论 - 这是因为
vbNullstring
是 空指针:
Debug.Print StrPtr(vbNullString) '<-- 0
InputBox
中的错误行为.如果微软要修复实现(他们不会),它会破坏你的代码(这就是他们不会的原因)。但总的来说,最好不要依赖这样的狡猾行为。除非您希望将点击“取消”的用户与不输入任何内容并点击“回车”的用户区别对待,否则使用
StrPtr(result) = 0
真的没有多大意义。赞成更清晰的
Len(result) = 0
或
result = vbNullString
.我断言,如果您需要做出这种区分,您应该将自己的
UserForm
放在一起。并在您自己的对话框中明确处理取消和数据验证。
关于vba - 在 VBA 中使用 StrPtr 函数的好处和风险是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42015700/
在寻找一种方法来测试用户何时取消 InputBox ,我偶然发现了StrPtr功能。我相信它会检查一个变量是否曾经被赋值,如果它从未被赋值,则返回零,如果是,则返回一些神秘的数字。 好像是个有用的功能
为什么*strptr = 0会截断字符串?(C) 为什么ascii值30的0变成了0的null? 这里我对数字 0、字符串 0 和字符串 termianl 0 感到困惑。 您的解释将不胜感激。 最佳答
我正在使用 VS 2012: 这是我的情况: 我正在用 visual basic 编写一些代码,调用我用 C++ 编写的 dll 函数(也是使用 vs 2012 编写的)。我函数的参数之一采用 wch
在VB6中VarPtr应该返回变量的地址,在本例中是变量的地址 str它在堆栈上分配,并在内存中保存一个指向字符串的指针。 StrPtr (或 StrPtr )应该返回内存中分配的字符串的地址。 By
我是一名优秀的程序员,十分优秀!