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

发布于 2024-09-26 08:00:09 字数 2265 浏览 5 评论 0原文

我已经使用 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 的合适方法是什么?

使用升级向导,我得到以下信息;

<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

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

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

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

编译失败,出现这些错误;

“字符串”类型的值不能是 转换为 'Microsoft.VisualBasic.Compatibility.VB6.FixedLengthString'

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

“MyTypeBuffer”类型的值不能是 转换为“字符串”

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

倾城°AllureLove 2024-10-03 08:00:09

LSet 是 VB6 中一个相当古怪的语句:请参阅 说明在手册中

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

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

  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)

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文