将右值作为 ByRef 参数传递给 VB6?

Passing an rvalue as a ByRef parameter to VB6?

背景:我有一组共享公共 "interface" 的 VB6 DLL。无论本地安装哪个版本,都会通过 COM 互操作调用此接口的成员(来自 VB.Net 代码,我怀疑这可能很重要)。我今天注意到其中一个调用将 [我理解的] 右值(以下简称 "an rvalue")传递给 VB6 函数,该函数没有将该特定参数定义为 ByVal.

示例代码:

VB6:

Public Function VB6Function(input As String) As String
    ' Do interesting things with input
End Function

VB.Net:

' get an instance of the VB6 class and pass our trimmed localString to it
result = vb6Instance.VB6Function(localString.Trim())
' Do interesting things with localString

我还没有注意到更改 input 值的 VB6 代码实例,但我也没有对不同的 DLL 实现(有数百个)进行详尽搜索。

如果 VB6Functioninput 为 "an rvalue" 时更改了 input 的值,会发生什么情况?就此而言,为什么在传递 "an rvalue" 时此方法调用不会简单地出错?

What would happen if VB6Function did change the value of input when input is "an rvalue"?

没有。或者更确切地说,没什么有趣的。

当被调用函数更改其参数值时,对于该函数的内部,参数是由val 还是byref 提供的都没有区别。重要的是有一个特定类型的变量,因此可以对其进行操作。

For that matter, why doesn't this method invocation simply error out when "an rvalue" is passed?

为什么会报错?传递的参数是正确的类型(字符串),这才是最重要的。

VB 中没有右值的概念。
当您将所谓的右值传递给通过引用接受某些内容的方法时,编译器会自动将引用传递给右值实际所在的 temporary location 。该方法通过ref获取其值,调用者不关心指针。

localString.Trim() 分配并 returns 一个字符串。它有一个地址,可以传递。 您的代码 没有明确捕获该地址,但编译器将其传递给 VB6Function byref 没有问题。如果 VB6Function 更改值,它会更改临时位置指向的内容,这没有明显的区别,因为无论哪种方式调用后它都会被销毁。

至于为什么有些人可能更喜欢在VBA中接收字符串byref,就是为了避免每次调用函数时都复制整个字符串。在 VB.NET 中这不是问题,因为那里的字符串是不可变的,因此可以在不复制的情况下通过 byval 传递,但在 VBA 中情况并非如此,因此需要克隆 byval 字符串用于电话。人们通过指定 byref 来避免这种情况,尽管从技术上讲这使他们能够弄乱传递的变量。