【发布时间】:2024-01-16 16:45:01
【问题描述】:
背景:我有一组共享一个通用“接口”的 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
我还没有注意到更改input 值的 VB6 代码实例,但我也没有对不同的 DLL 实现进行详尽的搜索(有数百个)。
如果VB6Function 确实在input 是“右值”时改变了input 的值会发生什么?就此而言,为什么在传递“右值”时该方法调用不会简单地出错?
【问题讨论】:
-
将其视为 r 值是没有用的。 System.String 是不可变的,Trim() 的返回值不是额外的不可变的。 pinvoke marshaller 确保它保持这种状态,底层互操作类型是 BSTR。在调用之前用 SysAllocString() 创建,之后用 SysFreeString() 销毁。 VB6 运行时可以重新分配参数,但这只会导致其字符串被 SysFreeString 破坏。 .NET 字符串不会受到影响。
-
@HansPassant 谢谢。将其视为 r 值实际上似乎是导致我陷入兔子洞的误解。但那是因为我将“rvalue”与“immutable”混为一谈,所以我需要提出一个澄清问题,以确保我理解您关于“.NET 字符串不会受到影响”的评论。如果我调用
VB6Function(localString)并且该代码为input分配了一个新值,那么localString的值在VB6Function返回时会有所不同吗? -
@arootbeer 当然。这就是 byref 的主要目的。
-
@GSerg 我知道这是 ByRef 在 VB6 内 和 在 VB.Net 内的主要目的。我的问题是试图澄清调用 VB6 COM 服务器的 VB.Net COM 客户端的行为是否不同。我不清楚“在调用之前使用
SysAllocString()创建并在之后使用SysFreeString()销毁”是否意味着重新分配的值将在函数调用返回后仍然可用,或者将不仍然可用。 -
你试过了吗?
标签: com vb6 parameter-passing