1

我已经使用 UpgradeWizard 将一些在自定义类型中使用固定长度字符串的 VB6 代码升级到 VB .NET,并且在使用 LSet 方法时遇到了问题,我希望有人能帮助我。

现有的 VB6 代码(类型声明);

Public Type MyType
    PROP1       As String * 15
    PROP2       As String * 25
End Type

Public Type MyTypeBuffer
    Buffer As String * 40
End Type

示例用法;

LSet instOfMyTypeBuffer.Buffer = ...
LSet instOfMyType = instOfMyTypeBuffer

将其升级到 .NET 的合适方法是什么?

使用 UpgradeWizard,我得到以下信息;

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
 _
Public Structure MyType
    <VBFixedString(15),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst:=15)> _
    Dim PROP1 As FixedLengthString

    <VBFixedString(25),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst:=25)> _
    Dim PROP2 As FixedLengthString

    Public Shared Function CreateInstance() As MyType
        Dim result As New MyType
        result.PROP1 = New FixedLengthString(15)
        result.PROP2 = New FixedLengthString(25)
        Return result
    End Function
End Structure

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
 _
Public Structure MyTypeBuffer
    <VBFixedString(CLVHDR_REC_LENGTH),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst:=40)> _
    Dim Buffer As FixedLengthString
    Public Shared Function CreateInstance() As MyTypeBuffer
        Dim result As New MyTypeBuffer
        result.Buffer = New FixedLengthString(40)
        Return result
    End Function
End Structure

FixedLengthString 来自命名空间 Microsoft.VisualBasic.Compatibility.VB6。

升级向导失败的地方是 LSet。它产生了以下内容;

instOfMyTypeBuffer.Buffer = LSet(...)
instOfMyType = LSet(instOfMyTypeBuffer)

哪个无法编译,给出这些错误;

'String' 类型的值无法转换为 'Microsoft.VisualBasic.Compatibility.VB6.FixedLengthString'

未为“公共函数 LSet(源为字符串,长度为整数)为字符串”的参数“长度”指定参数

'MyTypeBuffer' 类型的值不能转换为 'String'

所以,我可以使用 ToString() 来获得其中的一部分,但仍然存在 LSet 方法调用本身的问题。我应该怎么做才能重新创建原始功能?升级向导是否给了我一个完全不合适的转换,或者它是否可以挽救成可用的东西?

4

1 回答 1

2

LSet 是 VB6 中一个相当古怪的语句:参见手册中的描述

  • 在字符串上使用时,它将原始字符串中的字符串左对齐并用空格替换任何剩余的字符。
  • 当用于用户定义类型时,它只是将内存从一种用户定义类型复制到另一种,即使它们有不同的定义。不建议这样做。

它在您拥有的代码中以一种特别古怪的方式使用。

  1. LSet instOfMyTypeBuffer.Buffer = ...
    这在 VB6 和迁移的 Vb.Net 中都是多余的。当您为固定长度的字符串分配新值时,无论如何它总是用空格填充!
    所以只需更改为(在 VB6 或 VB.Net 中)
    instOfMyTypeBuffer.Buffer = ...
  2. LSet instOfMyType = instOfMyTypeBuffer
    更有意思的。这会将内存从一种类型的实例复制到另一种类型的实例中,无需检查。吞咽!
    查看类型的定义,我认为这只是将前 15 个字符instOfMyBuffer放入 into instOfMyType.PROP1,其余 25 个字符放入instOfMyType.PROP2.
    我偶尔会看到这被用作处理从文件读取的固定长度字符串记录的一种丑陋方式。例如,前 15 个字符可能是一个人的名字,接下来的 25 个字符可能是姓氏。
    您可以只替换此代码(在 VB6 或 VB.Net 中)。
    instOfMyType.PROP1 = Left(instOfMyBuffer.Buffer, 15)
    instOfMyType.PROP2 = Mid(instOfMyBuffer.Buffer, 16)

Hans 建议放弃固定长度的字符串。如果这很容易——并且取决于你的代码库的其余部分,它可能很容易,也可能很难——这是一个很好的建议。

于 2010-10-05T16:55:52.660 回答