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

时间:2017-11-26 18:26:12

标签: 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)

结果是:

1636452 
110882980 
110882980 

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

1 个答案:

答案 0 :(得分:5)

传递的字符串ByVal传递BStr中包含的C字符串的第一个字符的地址。 StrPtr也是如此。

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

将Unicode传递给API调用

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

Dim ByteArr() as Byte
Var1="My Text"
ByteArr = Var1
APICall(ByteArr(0))
APICall(StrPtr(Var1))

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

字符串构建

另一方面,如果您是字符串构建,那么使用LeftRightMid 语句将其内置到VBA中,而不是功能(它们已超载)。

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

ByVal与ByRef

     

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

ByVal str As String 
     

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

ByRef str As String
     

按预期传递BSTR的地址。

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

  

<强> StrPtr

     

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

     

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

     

示例:

Dim lngCharAddress as Long
Dim strMyVariable as String
strMyVariable = "Some String"
lngCharAddress = StrPtr(strMyVariable) 
     

当您需要将指针传递给a时,可以使用此功能   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