Vb.net VBnet访问字节的单个位//位数组长度&;计数是否等于字节值?

Vb.net VBnet访问字节的单个位//位数组长度&;计数是否等于字节值?,vb.net,byte,bitarray,Vb.net,Byte,Bitarray,我正在尝试与一个PLC进行通信,该PLC接受/发送16位值,每一位都允许检查是否发生 为此,我一直在尝试使用.Net位数组,但结果并不成功 基线结构由两个字节的数组组成,两个字节都用值0初始化 当我使用其中一个字节创建一个新的位数组时,我希望得到一个8个值设置为false的数组情况并非如此 字节值为0时,位数组的长度和计数也为零。虽然我可以假设前导零已删除,但这似乎非常违反直觉 当我使用值为200的字节创建一个位数组时,我希望得到一个值为8的数组(真、真、假、假、真、假、假)。但是,我得到的是长

我正在尝试与一个PLC进行通信,该PLC接受/发送16位值,每一位都允许检查是否发生

为此,我一直在尝试使用.Net位数组,但结果并不成功

基线结构由两个字节的数组组成,两个字节都用值0初始化

当我使用其中一个字节创建一个新的位数组时,我希望得到一个8个值设置为false的数组情况并非如此

字节值为0时,位数组的长度和计数也为零。虽然我可以假设前导零已删除,但这似乎非常违反直觉

当我使用值为200的字节创建一个位数组时,我希望得到一个值为8的数组(真、真、假、假、真、假、假)。但是,我得到的是长度和计数为200的位数组

代码当前为:

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