Страницы

Поиск по вопросам

воскресенье, 15 декабря 2019 г.

Как на C# задавать расположение данных в памяти с точностью до бит с помощью структур

#c_sharp #c #struct #union


Есть структура на С, которая используется для распределения данных пакета по его
полям. В С# я новичок. Подскажите, пожалуйста, как реализовать ее на C#? Все, что пока
нашел, - возможность использовать атрибуты вроде [StructLayout(LayoutKind::Explicit)]
и [FieldOffset(n)]. (
FieldOffsetAttribute Class)
Проблема в том, что поле address должно занимать 6 бит, поле type - вообще два; а,
насколько я понял,  FieldOffset задает смещение поля кратно байту, а не биту.

Собственно структура на С:

struct SExpandedPackage
{
    unsigned char address : 6;
    unsigned char type    : 2;
    unsigned char adata   : 4;
    unsigned char command : 4;
    unsigned char data       ;
    unsigned char crc        ;
};

union uPackageContainer
{
    unsigned long      bits;
    unsigned char      bytes[sizeof(unsigned long)];
    struct SExpandedPackage   expanded;
};

    


Ответы

Ответ 1



Для себя вопрос решил. Поля, составляющие 1 байт - в нем и хранятся (Это address и type, command и adata). Доступ к ним осуществляю с помощью битовых масок, которые применяются в соответствующих геттерах и сеттерах. Еще раз - спасибо MSDN.'Reinstate Monica' Knight за толчок в нужном направлении, и PashaPash за помощь в оформлении! Код на С#: [StructLayout(LayoutKind.Explicit)] public struct PackageContainer { private const byte _pkg_type = 0xC0; private const byte _pkg_address = 0x3F; private const byte _pkg_cmd = 0xF0; private const byte _pkg_adata = 0x0F; [FieldOffset(0)] private byte pkg_type; [FieldOffset(0)] private byte pkg_address; [FieldOffset(1)] private byte pkg_cmd; [FieldOffset(1)] private byte pkg_adata; public byte Pkg_Type { // 2-битное значение get { return (byte)((pkg_type & _pkg_type) >> 6); } set { pkg_type = (byte)((pkg_type & ~_pkg_type) | (value << 6) & _pkg_type); } } public byte Pkg_Address { // 6-битное значение get { return (byte)(pkg_address & _pkg_address); } set { pkg_address = (byte)((pkg_address & ~_pkg_address) | (_pkg_address & value)); } } } *Еще хорошо помогла статья на Хабре.

Комментариев нет:

Отправить комментарий