Преобразование пользовательского типа VB6 (со строками фиксированной длины) в VB .NET - PullRequest
1 голос
/ 05 октября 2010

Я обновил некоторый код VB6, который использует строки фиксированной длины в пользовательских типах, до VB .NET с помощью UpgradeWizard, и у меня возникли проблемы с использованием метода 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 (источник как строка, длина как Integer) As String '

Значение типа 'MyTypeBuffer' не может быть конвертируется в 'String'

Итак, я могу использовать ToString (), чтобы пройти часть пути туда, но все еще существует проблема самого вызова метода LSet. Что я должен сделать, чтобы воссоздать оригинальную функциональность? Мастер обновления дал мне совершенно неуместное преобразование, или его можно превратить в нечто пригодное для использования?

1 Ответ

2 голосов
/ 05 октября 2010

LSet - довольно странное утверждение в VB6: см. описание в руководстве .

  • При использовании со строками выравнивает по левому краю строку в исходной строке и заменяет все оставшиеся символы пробелами.
  • При использовании с пользовательскими типами просто копирует память из одного пользовательского типа поверх другого, даже если они имеют разные определения.Это не рекомендуется.

Это используется особенно странным образом в вашем коде.

  1. LSet instOfMyTypeBuffer.Buffer = ...
    Это избыточно как в VB6, так и в перенастроенном Vb.Net.Когда вы присваиваете новое значение строке фиксированной длины, она всегда в любом случае дополняется пробелами!
    Так что просто измените это (в VB6 или VB.Net)
    instOfMyTypeBuffer.Buffer = ...
  2. LSet instOfMyType = instOfMyTypeBuffer
    Более интересно.Это копирует память из экземпляра одного типа в экземпляр другого типа без проверок. Gulp!
    Глядя на определения типов, я думаю, что это просто помещает первые 15 символов из instOfMyBuffer в instOfMyType.PROP1, а оставшиеся 25 символов в instOfMyType.PROP2.
    Iвремя от времени видел, что это используется как ужасный способ обработки строковых записей фиксированной длины, считанных из файла.Например, первые пятнадцать символов могут быть именем человека, а следующие 25 - фамилией.
    Вы можете просто заменить этим кодом (в VB6 или VB.Net).
    instOfMyType.PROP1 = Left(instOfMyBuffer.Buffer, 15)
    instOfMyType.PROP2 = Mid(instOfMyBuffer.Buffer, 16)

Ганс предложил отказаться от струн фиксированной длины.Если это легко - и это зависит от остальной части вашей базы кода, может быть простым или может быть сложным - это хороший совет.

...