Converting Fixed length statement from VB6 to VB.Net

女生的网名这么多〃 提交于 2019-12-13 04:34:00

问题


We perform a protocol based data sending to device where the device requires a formatted data packets.

the sample packet data is XXFSXXXFSXXXXXXXFSXXXXXX. The X mentioned is the max length size of each string. if data is less than string max length it should be filled with NULL character like ..11FS123FS1234XXXX (the remaining X will be filled with NULL).

I am just trying to convert one of VB6 function to VB.Net and below is the converted statement where i am facing issue

Option Strict Off
Option Explicit On
Imports Microsoft.VisualBasic.Compatibility.VB6
Imports System
Imports System.Runtime.InteropServices
Module FunctionCmd_Msg

    Public FunCommand_Msg As Fun_CommandMessage = Fun_CommandMessage.CreateInstance()
    'Function Command Message
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _ _
    Public Structure Fun_CommandMessage
        <VBFixedString(1)> Public one As String
        <VBFixedString(1)> Public two As String
        <VBFixedString(3)> Public three As String
        Dim five As String
        <VBFixedString(8)> Public four As String
        Public Shared Function CreateInstance() As Fun_CommandMessage
            Dim result As New Fun_CommandMessage
            result.one = String.Empty
            result.two = String.Empty
            result.three = String.Empty
            result.four = String.Empty
            result.five = String.Empty
        End Function
    End Structure
End Module

assuming:

one = "1"
two = "1"
three = "123"
four = "5678"           
five = "testing"
FS = character (field separator)

on concatenating the strings i need a fixed length string such like this:

one & two & FS & three & FS & five & FS & four

output: since four is a fixed length string of 8 length remaining 4 characters should be filled with null as below

11 FS 123 FS testing FS 5678XXXX

回答1:


Fixed-length strings simply make no sense in .NET any more. Microsoft tried to provide a similar class for easier upgrade but the truth is that you should change your code depending on usage:

What did the fixed-length string do in your VB6 code? Was it for no good reason? Then use a normal String in .NET.

Was it for interop with a C API? Then use marshalling to set a size for an array in the C API call.




回答2:


Just forget about the fixed length, and use regular vb.net strings. They will return fine to whatever calls that code, including interop.

So, just pad your strings, and you off to the races.

In fact, build a Msg class that does the dirty work for you.

This looks quite nice to me:

NOTE how I set this up that you ONLY define the length of the string in ONE place. (so I use len(m_string) to determine the length from THEN on in the code.

Also, for debug and this example, in place of vbcharNull (which you should use), I used X for testing.

Now, in your code?

Just use this:

    Dim Msg As New MyMsg

    With Msg
        .one = "A"
        .two = "B"
        .three = "C"
        .four = "D"
        .Five = "E"
    End With

    Debug.WriteLine(Msg.Msg("*") & vbCrLf)

    Debug.WriteLine("total lenght = " & Len(Msg.Msg("X").ToString))

Output:

A*B*CXX*EXXXXXXX*DXXXXXXX

total lenght = 25

I note in your code that you have FIVE before FOUR - but if that is what you want, then no problem

Note that the class ALWAYS maintains the lengths for you.

So just paste this code into your module or even a new separate class.

Public Class MyMsg
    'Dim cPad As Char = vbNullChar
    Dim cPad As Char = "X"

    Private m_one As String = New String(cPad, 1)
    Private m_two As String = New String(cPad, 1)
    Private m_three As String = New String(cPad, 3)
    Private m_four As String = New String(cPad, 8)
    Private m_five As String = New String(cPad, 8)

    Public Property one As String
        Get
            Return m_one
        End Get
        Set(value As String)
            m_one = MyPad(value, m_one)
        End Set
    End Property
    Public Property two As String
        Get
            Return m_two
        End Get
        Set(value As String)
            m_two = MyPad(value, m_two)
        End Set
    End Property

    Public Property three As String
        Get
            Return m_three
        End Get
        Set(value As String)
            m_three = MyPad(value, m_three)
        End Set
    End Property

    Public Property four As String
        Get
            Return m_four
        End Get
        Set(value As String)
            m_four = MyPad(value, m_four)
        End Set
    End Property

    Public Property Five As String
        Get
            Return m_five
        End Get
        Set(value As String)
            m_five = MyPad(value, m_five)
        End Set
    End Property


    Public Function Msg(FS As String) As String
        Return m_one & FS & m_two & FS & m_three & FS & m_five & FS & m_four
    End Function

    Private Function MyPad(str As String, strV As String) As String
        Return Strings.Left(str & New String(Me.cPad, Len(strV)), Len(strV))
    End Function

End Class

As noted, change the commented out line of "X" for the char back to vbCharNull.

And of course you STILL get to choose the delimiter. I used

Msg.Msg("*") 

so I used a "*", but you can use space, or anything you want.



来源:https://stackoverflow.com/questions/11826460/converting-fixed-length-statement-from-vb6-to-vb-net

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