Converting VB6 Custom Type (with Fixed Length Strings) to VB .NET

本秂侑毒 提交于 2020-01-21 09:42:05

问题


I have upgraded some VB6 code, which uses fixed length strings in custom types, to VB .NET by using the UpgradeWizard and am having trouble with the use of the LSet method that I was hoping someone could help me out with.

The Existing VB6 code (type declarations);

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

Public Type MyTypeBuffer
    Buffer As String * 40
End Type

Example usage;

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

What would be an appropriate way to upgrade this to .NET?

Using the UpgradeWizard, I get the following;

<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 is coming from the namespace Microsoft.VisualBasic.Compatibility.VB6.

Where the Upgrade Wizard fails is when it comes to LSet. It produced the following;

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

Which fails to compile, giving these errors;

Value of type 'String' cannot be converted to 'Microsoft.VisualBasic.Compatibility.VB6.FixedLengthString'

Argument not specified for parameter 'Length' of 'Public Function LSet(Source As String, Length As Integer) As String'

Value of type 'MyTypeBuffer' cannot be converted to 'String'

So, I can use ToString() to get part of the way there, but there is still the issue of the LSet method call itself. What should I do to recreate the original functionality? Has the Upgrade Wizard given me a totally inappropriate conversion, or is it salvageable into something usable?


回答1:


LSet is a rather quirky statement in VB6: see description in the manual.

  • When used on strings, it left-aligns the string in the original string and replaces any leftover characters with spaces.
  • When used on user-defined types, it just copies the memory from one user-defined type over the other, even if they had different definitions. This is not recommended.

It's being used in a particularly quirky way in the code you have.

  1. LSet instOfMyTypeBuffer.Buffer = ...
    This is redundant both in the VB6 and the migrated Vb.Net. When you assign a new value to a fixed-length string, it always pads out with spaces anyway!
    So just change to this (in either VB6 or VB.Net)
    instOfMyTypeBuffer.Buffer = ...
  2. LSet instOfMyType = instOfMyTypeBuffer
    More interesting. This copies the memory from an instance of one type into an instance of another type, with no checks. Gulp!
    Looking at the definitions of the types, I think this simply puts the first 15 characters from instOfMyBuffer into instOfMyType.PROP1 and the remaining 25 characters into instOfMyType.PROP2.
    I have occasionally seen this used as an ugly way of processing fixed-length string records read from a file. For example the first fifteen characters might be a person's first name, and the next 25 the last name.
    You could just replace with this code (in either VB6 or VB.Net).
    instOfMyType.PROP1 = Left(instOfMyBuffer.Buffer, 15)
    instOfMyType.PROP2 = Mid(instOfMyBuffer.Buffer, 16)

Hans suggested ditching the fixed-length strings. If that's easy - and it depends on the rest of your code base, it might be easy, or it might be hard - it's good advice.



来源:https://stackoverflow.com/questions/3864422/converting-vb6-custom-type-with-fixed-length-strings-to-vb-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!