我想将代码从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
抱歉,我不能写好英语。
答案 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类作为替代方案,听起来并不像您对其仍然能够维护此代码的方式有足够的记忆。