背景:我有一组共享公共“接口”的VB6 DLL。无论本地安装了哪个版本,都可以通过COM互操作调用该接口的成员(从VB.Net代码,我怀疑这可能很重要)。我今天注意到,调用之一将[我理解为]右值(以下称为“右值”)传递给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
我尚未注意到VB6代码的实例更改的值input
,但是我也没有详尽搜索不同的DLL实现(有数百种)。
如果VB6Function
更改input
wheninput
为“ rvalue”的值会发生什么?为此,为什么在传递“右值”时此方法调用不会简单地出错?
如果输入为“右值”时VB6Function确实更改了输入的值,将会发生什么?
没有。或者说,没什么有趣的。
当被调用函数更改其参数的值时,无论该参数由byval还是byref提供,对该函数的内部都没有影响。重要的是存在某种类型的变量,因此可以对其进行操作。
为此,为什么在传递“右值”时此方法调用不会简单地出错?
为什么会出错?传递的参数是正确的类型(字符串),这很重要。
在VB中没有右值的概念。
当您将所谓的右值传递给通过引用接受某些内容的方法时,编译器会自动将引用传递到右值实际驻留的临时位置。该方法获取其值byref,调用者不在乎指针。
localString.Trim()
分配并返回一个字符串。它有一个地址,可以传递。您的代码没有显式捕获该地址,但是编译器将其传递给VB6Function
byref没有问题。如果VB6Function
更改该值,它将更改该临时位置所指向的内容,这没有明显的区别,因为它将在调用后以任何一种方式销毁。
至于为什么有些人可能更喜欢在VBA中通过byref接收字符串,这是特别避免在每次调用函数时都复制整个字符串。在VB.NET中,这不是问题,因为那里的字符串是不可变的,因此可以按字节传递而不进行复制,但是在VBA中则不是这样,因此出于调用的目的,必须克隆一个byval字符串。人们通过指定byref来避免这种情况,尽管从技术上讲,它们使他们有能力弄乱传递的变量。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句