将VB6自定义类型(带有固定长度字符串)转换为VB .NET

时间:2010-10-05 14:08:20

标签: .net vb6 vb6-migration

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

现有的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(Source As String,Length As   整数)作为字符串'

     

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

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

1 个答案:

答案 0 :(得分:2)

LS4在VB6中是一个相当古怪的陈述:见description in the manual

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

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

  1. LSet instOfMyTypeBuffer.Buffer = ...
    这在VB6和迁移的Vb.Net中都是多余的。当您为固定长度的字符串分配新值时,它总是用空格填充!
    所以只需改为(在VB6或VB.Net中) instOfMyTypeBuffer.Buffer = ...
  2. LSet instOfMyType = instOfMyTypeBuffer
    更有趣的。这会将内存从一种类型的实例复制到另一种类型的实例中,而不进行检查。的咕嘟咕嘟!
    查看类型的定义,我认为这只会将instOfMyBuffer中的前15个字符放入instOfMyType.PROP1,将剩余的25个字符放入instOfMyType.PROP2
    我偶尔会看到这被用作处理从文件读取的固定长度字符串记录的丑陋方式。例如,前15个字符可能是一个人的名字,而下一个25个字符可能是姓氏 您可以使用此代码替换(在VB6或VB.Net中) instOfMyType.PROP1 = Left(instOfMyBuffer.Buffer, 15)
    instOfMyType.PROP2 = Mid(instOfMyBuffer.Buffer, 16)
  3. 汉斯建议抛弃固定长度的琴弦。如果这很容易 - 这取决于你的代码库的其余部分,可能很容易,或可能很难 - 这是一个很好的建议。