在退出时将vb6迁移到vb.net

时间:2014-01-13 07:16:10

标签: vb.net vb6 vb6-migration

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

在压缩功能中,它已经成功。我很开心。但是当解压缩子没有成功。程序挂了。我试过修复它,我发现问题是这样做..退出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..exit do ..

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
抱歉,我不能写好英语。

1 个答案:

答案 0 :(得分:6)

  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。我猜想Integer在这里是合适的。请考虑将.NET GZipStream类作为替代方案,听起来并不像您对其仍然能够维护此代码的方式有足够的记忆。