【问题标题】:migrate vb6 to vb.net do while exit do将 vb6 迁移到 vb.net do while exit do
【发布时间】:2014-01-13 17:50:51
【问题描述】:

我想将代码从 vb6 迁移到 vb.net。 该项目非常基础(不使用 dll 或组件引用)只是模块

在压缩功能中,已经成功。我很开心。但是当解压子不成功。该程序被挂起。我尝试修复它,我发现问题是 do.. exit do..loop 语句。

注意:代码在vb6中运行成功。

这是我的解压代码

Public Sub Decompress(ByteArray() As Byte)
Dim InpPos As Long
Dim InBitPos As Integer
Dim LowValue As Long
Dim HighValue As Long
Dim RangValue As Long
Dim MidValue As Long
Dim Value As Long
Dim mChar As Byte
Dim i As Integer
Dim Index As Integer
Dim EOF_State As Boolean
Dim TopBit As Long
Dim One(256) As Long
Dim Zero(256) As Long
Call Initiate
LowValue = 0
HighValue = (2 ^ MaxBits) - 1
TopBit = 2 ^ (MaxBits - 1)
InpPos = 0
Value = ReadBitsFromArray(ByteArray, InpPos, InBitPos, MaxBits)
Index = -1
For i = 0 To 256
    One(i) = 1
    Zero(i) = 1
Next
Do
    mChar = 0
    For i = 0 To 7
        Index = (1 * (2 ^ i)) - 1 + mChar
        RangValue = HighValue - LowValue
        MidValue = LowValue + (RangValue * (Zero(Index) / (One(Index) + Zero(Index))))
        If MidValue = LowValue Then MidValue = MidValue + 1
        If MidValue = HighValue - 1 Then MidValue = MidValue - 1
        If Value >= MidValue Then
            mChar = (2 * mChar) + 1
            LowValue = MidValue
            One(Index) = One(Index) + 1
        Else
            mChar = 2 * mChar
            HighValue = MidValue
            Zero(Index) = Zero(Index) + 1
        End If

        Do While (HighValue And TopBit) = (LowValue And TopBit) Or LowValue > HighValue - 255
            If InpPos <= UBound(ByteArray) Then
                Value = (Value And (TopBit - 1)) * 2 + ReadBitsFromArray(ByteArray, InpPos, InBitPos, 1)
                HighValue = (HighValue And (TopBit - 1)) * 2 + 1
                LowValue = (LowValue And (TopBit - 1)) * 2
                If LowValue >= HighValue Then HighValue = (2 ^ MaxBits) - 1
            Else
                EOF_State = True
                Exit Do
            End If
        Loop
        If EOF_State = True Then Exit Do
    Next
    Call AddmCharToArray(OutStream, OutPos, mChar)
Loop
ReDim Preserve OutStream(OutPos - 1)
End Sub

Private Sub Initiate()
ReDim OutStream(500)
OutPos = 0
OutBitCount = 0
OutByteBuf = 0
End Sub

Private Sub AddBitsToOutStream(Number As Integer)
OutByteBuf = OutByteBuf * 2 + Number
OutBitCount = OutBitCount + 1
If OutBitCount = 8 Then
    OutStream(OutPos) = OutByteBuf
    OutBitCount = 0
    OutByteBuf = 0
    OutPos = OutPos + 1
    If OutPos > UBound(OutStream) Then
        ReDim Preserve OutStream(OutPos + 500)
    End If
End If
End Sub

Private Function ReadBitsFromArray(FromArray() As Byte, FromPos As Long, FromBit As Integer, NumBits As Integer) As Long
Dim i As Integer
Dim Temp As Long
For i = 1 To NumBits
    Temp = Temp * 2 + (-1 * ((FromArray(FromPos) And 2 ^ (7 - FromBit)) > 0))
    FromBit = FromBit + 1
    If FromBit = 8 Then
        If FromPos + 1 > UBound(FromArray) Then
            Do While i < NumBits
                Temp = Temp * 2
                i = i + 1
            Loop
            FromPos = FromPos + 1
            Exit For
        End If
        FromPos = FromPos + 1
    FromBit = 0
    End If
Next
ReadBitsFromArray = Temp
End Function

Private Sub AddmCharToArray(ToArray() As Byte, ToPos As Long, mChar As Byte)
If ToPos > UBound(ToArray) Then ReDim Preserve ToArray(ToPos + 500)
ToArray(ToPos) = mChar
ToPos = ToPos + 1
End Sub

做..退出做..

Do
    mChar = 0
    For i = 0 To 7
        Index = (1 * (2 ^ i)) - 1 + mChar
        RangValue = HighValue - LowValue
        MidValue = LowValue + (RangValue * (Zero(Index) / (One(Index) + Zero(Index))))
        If MidValue = LowValue Then MidValue = MidValue + 1
        If MidValue = HighValue - 1 Then MidValue = MidValue - 1
        If Value >= MidValue Then
            mChar = (2 * mChar) + 1
            LowValue = MidValue
            One(Index) = One(Index) + 1
        Else
            mChar = 2 * mChar
            HighValue = MidValue
            Zero(Index) = Zero(Index) + 1
        End If

        Do While (HighValue And TopBit) = (LowValue And TopBit) Or LowValue > HighValue - 255
            If InpPos <= UBound(ByteArray) Then
                Value = (Value And (TopBit - 1)) * 2 + ReadBitsFromArray(ByteArray, InpPos, InBitPos, 1)
                HighValue = (HighValue And (TopBit - 1)) * 2 + 1
                LowValue = (LowValue And (TopBit - 1)) * 2
                If LowValue >= HighValue Then HighValue = (2 ^ MaxBits) - 1
            Else
                EOF_State = True
                Exit Do
            End If
        Loop
        If EOF_State = True Then Exit Do
    Next
    Call AddmCharToArray(OutStream, OutPos, mChar)
Loop

对不起,我的英文写得不好。

【问题讨论】:

    标签: vb.net vb6 vb6-migration


    【解决方案1】:
      Private Function ReadBitsFromArray(FromArray() As Byte, FromPos As Long, ...)
    

    错误位于此函数声明中。只有当InpPos 增加超出数组的上限时,您的循环才能退出,将EOF_State 变量设置为True。循环本身根本不会增加 InpPos。回到 VB6,它由 ReadBitsFromArray() 函数增加,FromBit = FromBit + 1 语句。但在 VB.NET 中不再是这种情况了。

    VB.NET 的一个重要变化是参数的传递方式。旧的 Visual Basic 版本默认为 ByRef。一个有点奇怪的选择,其原因在时间的迷雾中消失了。这是一种非常昂贵的方式来传递参数,传递 ByRef 需要传递一个指向值的指针而不是值本身。并且每次访问变量都需要指针解引用。它比在现代机器上按值传递至少慢 3 倍,.NET 经过大量优化以通过 CPU 寄存器而不是堆栈传递参数值,如果参数通过引用传递,则无法工作。

    所以 VB.NET 将 ByVal 设为默认值。由于您没有明确声明它,因此默认值适用并且 InpPos 是按值传递的。永远不要增加,在调试器中很容易看到的东西。修复:

    Private Function ReadBitsFromArray(ByVal FromArray() As Byte, _
                                       ByRef FromPos As Integer, _
                                       ByVal FromBit As Integer, _
                                       ByVal NumBits As Integer) As Integer
    

    请注意,在 Long 和 Integer 之间进行选择是您必须担心的另一件事。 VB6 Long 是一个 VB.NET 整数。我猜 Integer 在这里是合适的。请考虑将 .NET GZipStream 类作为替代方案,听起来您对它的工作方式记忆不够,仍然能够维护此代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-10
      • 2011-07-19
      • 1970-01-01
      • 1970-01-01
      • 2013-12-01
      • 2018-05-09
      相关资源
      最近更新 更多