C Битовые поля в C #

Мне нужно перевести структуру C в C #, который использует битовые поля.

typedef struct foo  
{  
    unsigned int bar1 : 1;
    unsigned int bar2 : 2;
    unsigned int bar3 : 3;
    unsigned int bar4 : 4;
    unsigned int bar5 : 5;
    unsigned int bar6 : 6;
    unsigned int bar7 : 7;
    ...
    unsigned int bar32 : 32;
} foo;

Кто-нибудь знает, как это сделать, пожалуйста?


person David    schedule 25.02.2011    source источник
comment
Уже ответил в Битовых полях в C #.   -  person Aasmund Eldhuset    schedule 25.02.2011
comment
Надеюсь, вы знаете, что выделяете 1 + 2 + 3 .. +32 бита = 528 бит = 66 байтов.   -  person Lundin    schedule 25.02.2011
comment
@Lundin: Это просто пример, я просто хотел указать, что у меня есть все возможные варианты битовых полей.   -  person David    schedule 25.02.2011
comment
@Aasmund Eldhuset: Да, я уже видел этот пост, но я не понимаю, почему он конвертирует все uint в один длинный.   -  person David    schedule 25.02.2011
comment
@David Я думаю, он просто хотел продемонстрировать, что битовая маска закончилась так, как хотелось, и он предположил, что 64 бит должно быть достаточно для всех ... ;-) Однако его решение не экономит место (я не понимал это до сих пор), поскольку каждый элемент его структуры представляет собой полный uint. Если вам действительно нужно сэкономить место или необходимо взаимодействовать с оборудованием (что, я думаю, является единственной оправданной причиной использования битовых полей в первую очередь), вам следует подумать об использовании BitArray, как предлагает @Nekresh, и, возможно, обернуть его в свойствах, которые получить / установить группы битов (правда, немного поработать).   -  person Aasmund Eldhuset    schedule 25.02.2011
comment
Вы пытаетесь упорядочить данные? В противном случае вы могли бы просто написать свой собственный BitField класс, что было бы очень просто.   -  person Marlon    schedule 25.02.2011
comment
Я думаю, вам нужно сначала уточнить, КАК вы собираетесь использовать это struct.   -  person John Alexiou    schedule 15.05.2013


Ответы (4)


Как объясняется в этом ответе и эту статью MSDN, вы можете искать следующее вместо BitField

[Flags]
enum Foo
{
    bar0 = 0,
    bar1 = 1,
    bar2 = 2,
    bar3 = 4,
    bar4 = 8,
    ...
}

так как вычисление 2 32 может быть немного утомительным, вы также можете сделать это:

[Flags]
enum Foo
{
    bar0 = 0,
    bar1 = 1 << 0,
    bar2 = 1 << 1,
    bar3 = 1 << 2,
    bar4 = 1 << 3,
    ...
}

И вы можете получить доступ к своим флагам, как и ожидаете в C:

Foo myFoo |= Foo.bar4;

а C # в .NET 4 бросает вам вызов с помощью метода HasFlag().

if( myFoo.HasFlag(Foo.bar4) ) ...
person Community    schedule 15.05.2013

Вы можете использовать класс BitArray для фреймворка. Прочтите статью msdn.

person Nekresh    schedule 25.02.2011
comment
Спасибо, но это было бы головной болью, если бы мне пришлось объявить все до единого. - person David; 25.02.2011

К сожалению, в C # такого нет. Самое близкое - это применение атрибута StructLayout и использование атрибута FieldOffset для полей. Однако смещение поля указывается в байтах, а не в битах. Вот пример:

[StructLayout(LayoutKind.Explicit)]
struct MyStruct
{
    [FieldOffset(0)]
    public int Foo; // this field's offset is 0 bytes

    [FieldOffset(2)]
    public int Bar; // this field's offset is 2 bytes. It overlaps with Foo.
}

Но это НЕ то же самое, что вам нужно.

Если вам нужно декодировать последовательность битов в структуру, вам придется написать ручной код (используя, например, такие классы, как MemoryStream или BitConverter).

person Alex Shtof    schedule 25.02.2011
comment
›Если вам нужно декодировать последовательность битов в структуру, вам придется писать код вручную (используя, например, такие классы, как MemoryStream или BitConverter). Что ж, это было то, что я искал. - person David; 25.02.2011

Вы ищете атрибут FieldOffset? См. Здесь: Класс FieldOffsetAttribute

person Simon Mourier    schedule 25.02.2011