Распределение записей с битовыми полями в C #

2

Можно ли объединить структуру C-стиля, содержащую бит-поля, в структуру С#, или вы должны были бы маршалировать ее на базовый тип, а затем делать бит-маски?

например. Я хотел бы маршалировать из структуры стиля C следующим образом:

struct rgb16 {
    unsigned int R : 4;
    unsigned int G : 5;
    unsigned int B : 4;
}

И выделите его на что-то вроде этого:

[StructLayout(LayoutKind.Sequential)]
public struct Rgb16 {
    public byte R;
    public byte G;
    public byte B;
}
Теги:
bit-fields
marshalling

3 ответа

4
Лучший ответ

В С# нет бит-полей. Таким образом, я бы пошел со свойствами, которые инкапсулируют бит fiddling:

[StructLayout(LayoutKind.Sequential)]
public struct Rgb16 {
    private readonly UInt16 raw;
    public byte R{get{return (byte)((raw>>0)&0x1F);}}
    public byte G{get{return (byte)((raw>>5)&0x3F);}}
    public byte B{get{return (byte)((raw>>11)&0x1F);}}

    public Rgb16(byte r, byte g, byte b)
    {
      Contract.Requires(r<0x20);
      Contract.Requires(g<0x40);
      Contract.Requires(b<0x20);
      raw=r|g<<5|b<<11;
    }
}

Я избегал добавлять сеттеры, потому что мне нравятся неизменные структуры, но в принципе вы можете их добавить.

  • 0
    Довольно много, как я делал это до сих пор. Я надеялся, что что-то упустил, но, думаю, лучше всего .
2

Это мой "безопасный С#" порт структуры rgb16.

[StructLayout(LayoutKind.Explicit, Size = 2, Pack = 1)]
public class Color16
{
    // Btifield: 5
    [FieldOffset(0)]
    private ushort b_i;

    public ushort b
    {
        get { return (ushort)((b_i >> 11) & 0x1F); }
        set { b_i = (ushort)((b_i & ~(0x1F << 11)) | (value & 0x3F) << 11); }
    }

    // Bitfield: 6
    [FieldOffset(0)]
    private ushort g_i;

    public ushort g
    {
        get { return (ushort)((g_i >> 5) & 0x7F); }
        set { g_i = (ushort)((g_i & ~(0x7F << 5)) | (value & 0x7F) << 5); }
    }

    // Bitfield: 5
    [FieldOffset(0)]
    private ushort r_i;

    public ushort r
    {
        get { return (ushort) (r_i & 0x1F); }
        set { r_i = (ushort) ((r_i & ~0x1F) | (value & 0x1F)); }
    }

    [FieldOffset(0)]
    public ushort u;

    public Color16() { }
    public Color16(Color16 c) { u = c.u; }
    public Color16(ushort U) { u = U; }

}
0

У меня есть маршалированные битподы вроде:

public struct Rgb16 {
    public ushort Value; // two byte value that internally contain structure R(4):G(5):B(4)

    public Rgb16BitField GetBitField
    {
        get; set;
    }
}

где свойство создает новую структуру, как вы упомянули, деля значение Value на бит.

Не лучший способ сделать это, но не нашел ничего, что сработало для меня. Я могу предоставить код для GetBitField, если вы хотите (он не очень компактный)

Обновление: Ссылка, предоставленная Тони в комментариях к вашему вопросу, использует ту же идею, но кажется более точной, чем моя, поэтому используйте его решение, если вы не можете найти лучшего

Ещё вопросы

Сообщество Overcoder
Наверх
Меню