Vb.net VBnet访问字节的单个位//位数组长度&;计数是否等于字节值?
我正在尝试与一个PLC进行通信,该PLC接受/发送16位值,每一位都允许检查是否发生 为此,我一直在尝试使用.Net位数组,但结果并不成功 基线结构由两个字节的数组组成,两个字节都用值0初始化 当我使用其中一个字节创建一个新的位数组时,我希望得到一个8个值设置为false的数组情况并非如此 字节值为0时,位数组的长度和计数也为零。虽然我可以假设前导零已删除,但这似乎非常违反直觉 当我使用值为200的字节创建一个位数组时,我希望得到一个值为8的数组(真、真、假、假、真、假、假)。但是,我得到的是长度和计数为200的位数组 代码当前为:Vb.net VBnet访问字节的单个位//位数组长度&;计数是否等于字节值?,vb.net,byte,bitarray,Vb.net,Byte,Bitarray,我正在尝试与一个PLC进行通信,该PLC接受/发送16位值,每一位都允许检查是否发生 为此,我一直在尝试使用.Net位数组,但结果并不成功 基线结构由两个字节的数组组成,两个字节都用值0初始化 当我使用其中一个字节创建一个新的位数组时,我希望得到一个8个值设置为false的数组情况并非如此 字节值为0时,位数组的长度和计数也为零。虽然我可以假设前导零已删除,但这似乎非常违反直觉 当我使用值为200的字节创建一个位数组时,我希望得到一个值为8的数组(真、真、假、假、真、假、假)。但是,我得到的是长
Private FaultBits as Byte = 0
Public Sub SetBitValue(index As Integer, value As Boolean)
Try
If index < 0 Then
Throw New Exception("Index is below zero!")
End If
If index > 7 Then
Throw New Exception("Index out of bounds! Maximum allowed index value is 7")
End If
'If BitConverter.IsLittleEndian Then
'ToDo
'End If
Dim bitArray_Section As BitArray = Nothing
bitArray_Section = New BitArray(FaultBits)
'bitArray_Section.Length = 8 'Truncates incorrectly
bitArray_Section.Item(index) = value 'Set the individual bit
FaultBits = ConvertToByte(bitArray_Section) 'Set back to byte
Catch ex As Exception
Throw New Exception("clsFaultBits : SetBitValue : w. Index " & index & " : Exception : " & ex.Message())
End Try
End Sub
字节为0的私有故障位
公共子SetBitValue(索引为整数,值为布尔值)
尝试
如果指数<0,则
抛出新异常(“索引低于零!”)
如果结束
如果索引>7,则
抛出新异常(“索引超出范围!允许的最大索引值为7”)
如果结束
'如果BitConverter.IsLittleEndian,则
“待办事项
"完"
Dim bitArray_部分为bitArray=Nothing
bitArray_Section=新的bitArray(FaultBits)
“bitArray_Section.Length=8”截断错误
bitArray_Section.Item(index)=value'设置单个位
FaultBits=ConvertToByte(位数组_部分)'设置回字节
特例
抛出新异常(“clsFaultBits:SetBitValue:w.Index”&Index&“:异常:&ex.Message())
结束尝试
端接头
和get等价物:
Public Function GetBitValue(index As Integer) As Boolean
Try
If index < 0 Then
Throw New Exception("Index is below zero!")
End If
If index > 7 Then
Throw New Exception("Index out of bounds! Maximum allowed index value is 7")
End If
Dim bitArray_Section As BitArray = Nothing
bitArray_Section = New BitArray(FaultBits)
'bitArray_Section.Length = 8
Return bitArray_Section.Item(index)
Catch ex As Exception
Throw New Exception("clsFaultBits : GetBitValue : w. Index " & index & " : Exception : " & ex.Message())
End Try
End Function
公共函数GetBitValue(索引为整数)为布尔值
尝试
如果指数<0,则
抛出新异常(“索引低于零!”)
如果结束
如果索引>7,则
抛出新异常(“索引超出范围!允许的最大索引值为7”)
如果结束
Dim bitArray_部分为bitArray=Nothing
bitArray_Section=新的bitArray(FaultBits)
'bitArray_Section.Length=8
返回bitArray\u节项(索引)
特例
抛出新异常(“clsFaultBits:GetBitValue:w.Index”&Index&“:异常:&ex.Message())
结束尝试
端函数
转换函数,我假设它的长度为8,这是错误的:
Public Function ConvertToByte(bits As BitArray) As Byte
Try
If bits.Count <> 8 Then
Throw New Exception("Invalid amount of bits!")
End If
Dim returnbyte(1) As Byte
bits.CopyTo(returnbyte, 0)
Return returnbyte(0)
Catch ex As Exception
Throw New Exception("clsFaultBits : ConvertToByte : Exception : " & ex.Message())
End Try
End Function
Public Function ConvertToByte(位作为位数组)作为字节
尝试
如果是位,那么数到8
抛出新异常(“无效的位数!”)
如果结束
Dim returnbyte(1)作为字节
位.CopyTo(返回字节,0)
返回字节(0)
特例
抛出新异常(“clsFaultBits:ConvertToByte:Exception:&ex.Message())
结束尝试
端函数
字节值::位数组长度/计数
0::0/0
200::200/200
10:10/10
我想实现的目标是:
接收一个字节(1-0-0-1-0-0-1-0)
通过读取单个位启用程序中的布尔值:
检查1,检查4,检查7
设置输出字节的各个位,从0-0-0-0-0-0-0-0-0-0开始
打开5:0-0-0-0-1-0-0-0
打开2:0-1-0-0-1-0-0-0
发送字节
我是否完全误用了BitArray类?我做错了什么?
什么能让我在不陷入混乱的情况下更改单个位值
为什么位数组的长度/计数与字节的值相同,而不是字节的组成位数
我知道代码还没有考虑endian ness
提前感谢,
已解决: 我没有意识到将非数组字节发送到BitArray会隐式地将其转换为整数,因此它会创建一个长度/计数等于字节值的BitArray。现在完全有道理了 这也让我意识到我的编译器对隐式转换的警告不会触发,因为字节到整数并不被视为隐式的,因为每当隐式转换发生时,我通常会收到通知
谢谢你的帮助 我不确定BitArray类是否是您所需要的。无论如何,不能从整数值创建位数组。例如,语句
新建位数组(200)
将创建一个包含200个项的位数组,所有项都设置为0。
如果需要发送16位值,我认为使用
UShort
(也称为UInt16
)数据类型而不是位数组会更简单,并使用@djv建议检查单个位。要设置位,必须使用一些“二进制”代数和和运算符。请记住始终使用无符号数据类型,并注意位计数从右开始。我不确定BitArray类是否是您所需要的。无论如何,不能从整数值创建位数组。例如,语句新建位数组(200)
将创建一个包含200个项的位数组,所有项都设置为0。
如果需要发送16位值,我认为使用UShort
(也称为UInt16
)数据类型而不是位数组会更简单,并使用@djv建议检查单个位。要设置位,必须使用一些“二进制”代数和和运算符。请记住始终使用无符号数据类型,并注意位计数从右开始。不幸的是,BitArray不允许您转换为16位值或从16位值转换为16位值
但是,它确实适用于Byte()和Integer()
因此,我们可以从/转换为32位整数,这应该可以正常工作
它也不是
Sub Testset()
Dim i16 As UInt16
i16 = 255
SetBits(i16, 9, False)
SetBits(i16, 9, True)
Debug.Print(GetBits(i16, 9).ToString)
End Sub
00000000 11111111
00000010 11111111
True
Public Sub SetBits(ByRef My16Bits As UInt16, MyINdex As Integer, MyValue As Boolean)
' toss the passed 16 bits into a 32 bit interger
' we do this, since the conversion routines only work
' for built in primitaves ike byte() or integer().
Dim My32(0) As Integer
My32(0) = My16Bits
Dim My32Bits As New BitArray(New Integer() {My32(0)})
My32Bits(MyINdex) = MyValue
' now convert bit array back to our 32 bit integer
My32Bits.CopyTo(My32, 0)
' now copy our 32 bit interger back to that 16 bit
My16Bits = My32(0)
For i = 15 To 0 Step -1
Debug.Write(IIf(My32Bits(i), "1", "0"))
If i = 8 Then Debug.Write(" ")
Next i
Debug.Print("")
End Sub
Public Function GetBits(My16Bits As UInt16, MyIndex As Integer) As Boolean
' convert Int16 to bit array
Dim My32(0) As Integer
My32(0) = My16Bits
Dim My32Bits As New BitArray(New Integer() {My32(0)})
Return My32Bits(MyIndex)
End Function