Click to See Complete Forum and Search --> : Structure containing bit mask


sb101
September 5th, 2008, 08:45 AM
I'm parsing a byte[] to a structure using StructLayout. I've managed to get this to work for integers, arrays, etc but I need to check for bits too. So something like this in C++.


struct
{
unsigned short one : 6;
unsigned short two : 5;
unsigned short three : 5;
} field;


I guess I need to use BitArray but I've been unbale to get this to work with StructLayout.

Could anyone point me in the correct direction?
Thank you.

nabeelisnabeel
September 5th, 2008, 09:18 AM
There is not concept of Bit mask in C# as there is in C++; Let someone correct me if I am wrong.

JonnyPoet
September 5th, 2008, 10:20 AM
Are you going to handle data between managed and unmanaged code so you need to use StructLayout ? Whats the exact problem you want to get handled with this?

Basically if you need to use a bitmask you can do it in the properties
of the struct

private int data;
public byte MyFirstBit{
get {return this.data & 0x00000001;}
set { // kill existing bit in this place
this.data &= 0x11111110;
// set new bit
this.data |= value & 0x00000001;
}
}Depending on your needs you also can use an indexer checking each bit you need using the index running from bit ti bit.

sb101
September 5th, 2008, 03:30 PM
I'm simply reading a byte[] from a file. This file has a pre-defined layout. So for example..

uint32 value1 (bytes 0 -3)
uint16 value2 (4-5)
byte value 3 (6)

I can get these values fine but value2 could then be broken down further.

value2 -> 1st 12bits are a numeric field and the remaining bits are single byte flags.

As you say I could use setter to parse the value correctly but I wanted to make sure it wasn't possible to do someting like:

uint32 value1
BitArray value 2_1[12]
BitArray value 2_2[1]
BitArray value 2_3[1]
BitArray value 2_4[1]
BitArray value 2_5[1]
byte value3

I hope this explains exactly what I hope to do. Maybe it's not possible and byte is the smallest "unit" for StructLayout.

Thanks.

MadHatter
September 5th, 2008, 03:42 PM
using System;
using System.Runtime.InteropServices;

static class Program {
static void Main() {
byte[] bytes = { 0x02, 0x16, 0xaf, 0xff, 0xaa, 0x00, 0x01 };
GCHandle bHand = GCHandle.Alloc(bytes, GCHandleType.Pinned);
Field f = (Field)Marshal.PtrToStructure(bHand.AddrOfPinnedObject(), typeof(Field));
bHand.Free();
// Here f will contain the values from the byte array
}
}

[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct Field {
[FieldOffset(0)]
public uint one;
[FieldOffset(sizeof(uint))]
public ushort two;
[FieldOffset(sizeof(uint) + sizeof(ushort))]
public byte three;
}

JonnyPoet
September 5th, 2008, 05:30 PM
...
I hope this explains exactly what I hope to do. Maybe it's not possible and byte is the smallest "unit" for StructLayout.
IMHO Byte is the smallest unit, and bits are handled by using bitmasks as I showed in my example.