为什么VarPtr(ByVal str)的结果与StrPtr(str)相同?(VB6)

Ite*_*tor 3 vb6

在VB6中VarPtr应返回变量的地址,在这种情况下str是在堆栈上分配的变量的地址,并保存指向内存中字符串的指针.StrPtr(或StrPtr)应该返回内存中已分配字符串的地址.ByVal应该只创建一个副本,但在这种情况下,它的工作原理很奇怪:

Dim str As String
str = "asd"
Debug.Print VarPtr(str)
Debug.Print VarPtr(ByVal str)
Debug.Print StrPtr(str)
Run Code Online (Sandbox Code Playgroud)

结果是:

1636452 
110882980 
110882980 
Run Code Online (Sandbox Code Playgroud)

为什么结果VarPtr(ByVal str)一样StrPtr(str)

ACa*_*ove 5

ByVal传递的字符串传递BStr中包含C字符串的第一个字符的地址.StrPtr做同样的事.

这样做有两个原因让人想起来.将Unicode传递给API调用和字符串构建.

将Unicode传递给API调用

StrPtr将Unicode字符串发送到API函数时,可以使用字符串而不是字节数组.

Dim ByteArr() as Byte
Var1="My Text"
ByteArr = Var1
APICall(ByteArr(0))
APICall(StrPtr(Var1))
Run Code Online (Sandbox Code Playgroud)

是否应该将Unicode字符串传递给API函数.使用declare语句时,Unicode字符串将转换为ANSI字符串,因为Win 95不执行unicode.

字符串构建

在如果你是字符串建筑另一方面,则是内置在VBA使用Left,RightMid 语句,而不是函数(他们过载).

Sub Main()
    Dim Var As String
    Var = "gggggggggggg"
    MsgBox StrPtr(Var)
    Mid(Var, 1, 2) = "xx"
    MsgBox StrPtr(Var) & " - " & Var
End Sub
Run Code Online (Sandbox Code Playgroud)

ByVal Versus ByRef

有些作者喜欢说ByVal关键字是为字符串重载的,这意味着当应用于字符串时它比应用于其他变量时具有不同的含义.坦率地说,我没有看到它.写作:

ByVal str As String 
Run Code Online (Sandbox Code Playgroud)

告诉VB传递BSTR的内容(实际上是ABSTR),它是指向字符数组的指针.因此,ByVal正常运行 - 它恰好发生在BSTR的内容是指向另一个对象的指针,因此这模拟了一个通过引用的传递.同理:

ByRef str As String
Run Code Online (Sandbox Code Playgroud)

按预期传递BSTR的地址.

使用Visual Basic进行W​​in32 API编程, 第6章字符串,O'Reilly,来自MSDN Library 2001年10月

StrPtr

Visual Basic中的字符串存储为BSTR.如果在String类型的变量上使用VarPtr,您将获得BSTR的地址,该地址是指向字符串指针的指针.要获取字符串缓冲区本身的地址,您需要使用StrPtr函数.此函数返回字符串第一个字符的地址.考虑到字符串在Visual Basic中存储为UNICODE.

要获取String的第一个字符的地址,请将String变量传递给StrPtr函数.

例:

Dim lngCharAddress as Long
Dim strMyVariable as String
strMyVariable = "Some String"
lngCharAddress = StrPtr(strMyVariable) 
Run Code Online (Sandbox Code Playgroud)

当需要将指向UNIOCODE字符串的指针传递给API调用时,可以使用此函数.

HOWTO:获取Visual Basic中的变量地址Q199824 Microsoft知识库,MSDN 2001年10月.

VarPtr不是VBA/VB6语言的一部分,因此实现VBA的公司(如Corel)可能无法在其VBA中实现它.VBA规范在这里https://msdn.microsoft.com/en-us/library/dd361851.aspx