本文介绍了将 VB6 自定义类型(具有固定长度字符串)转换为 VB .NET的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用 UpgradeWizard 将一些在自定义类型中使用固定长度字符串的 VB6 代码升级到 VB .NET,并且在使用 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.

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

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

用法示例;

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

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

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 来自命名空间 Microsoft.VisualBasic.Compatibility.VB6.

FixedLengthString is coming from the namespace Microsoft.VisualBasic.Compatibility.VB6.

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

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;

字符串"类型的值不能转换成'Microsoft.VisualBasic.Compatibility.VB6.FixedLengthString'

没有为参数指定参数公共职能"的长度"LSet(源为字符串,长度为整数)作为字符串'

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

MyTypeBuffer"类型的值不能转换为字符串"

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

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

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?

推荐答案

LSet 是 VB6 中一个相当古怪的语句:参见 说明书中的说明.

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

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

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

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

  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)
  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 建议放弃固定长度的字符串.如果这很容易 - 并且取决于您的代码库的其余部分,它可能很容易,或者它可能很难 - 这是个好建议.

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.

这篇关于将 VB6 自定义类型(具有固定长度字符串)转换为 VB .NET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 08:26