Как упорядочить структуру C ++, содержащую битовые поля DWORD в C #

1

Я работаю с неуправляемым SDK и имею структуру, которую мне нужно для маршала в С#:

struct DEV_TIME
{
    DWORD  second:6;
    DWORD  minute:6;
    DWORD  hour:5;
    DWORD  day:5;
    DWORD  month:4;
    DWORD  year:6;
}

Я искал вокруг и пробовал несколько вещей, но, похоже, не понял этого. Вот моя последняя попытка после чтения многочисленных сообщений:

    [StructLayout(LayoutKind.Sequential)]
    public struct DHDEVTIME
    {
        internal uint secData;
        internal uint minData;
        internal uint hourData;
        internal uint dayData;
        internal uint monData;
        internal uint yearData;

        public uint second
        {
            get { return secData & 0x3F; }
            set { secData = (secData % ~0x3Fu) | (value & 0x3F); }
        }

        public uint minute
        {
            get { return minData & 0x3F; }
            set { minData = (minData % ~0x3Fu) | (value & 0x3F); }
        }

        public uint hour
        {
            get { return hourData & 0x1F; }
            set { hourData = (hourData % ~0x1Fu) | (value & 0x1F); }
        }

        public uint day
        {
            get { return dayData & 0x1F; }
            set { dayData = (dayData % ~0x1Fu) | (value & 0x1F); }
        }

        public uint month
        {
            get { return monData & 0xF; }
            set { monData = (monData % ~0xFu) | (value & 0xF); }
        }

        public uint year
        {
            get { return yearData & 0x3F; }
            set { yearData = (yearData % ~0x3Fu) | (value & 0x3F); }
        }
    }

Эта структура является частью вызова SDK, который содержит другие структуры и т.д. И т.д. Короче говоря, я не уверен на 100%, если это даже неправильно, и это то, что заставляет вызов работать неправильно. Мне никогда не приходилось иметь дело с такой структурой, поэтому я думаю, что это наиболее вероятная причина. Если это окажется правильным, сообщите мне, и я отправлю еще один код. Сначала стараюсь быть минималистичным.

ОБНОВИТЬ

Спасибо @Ben Voigt за то, что указали мне в правильном направлении. Ниже приведен правильный код для использования в будущем:

[StructLayout(LayoutKind.Sequential)]
public struct DHDEVTIME
{
    internal uint data;

    public uint second
    {
        get { return data & 0x3F; }
        set { data = (data & ~0x3Fu) | (value & 0x3F); }
    }

    public uint minute
    {
        get { return (data >> 6) &  0x3F; }
        set { data = (data & ~(0x3Fu << 6)) | (value & 0x3F) << 6; }
    }

    public uint hour
    {
        get { return (data >> 12) & 0x1F; }
        set { data = (data & ~(0x1Fu << 12)) | (value & 0x1F) << 12; }
    }

    public uint day
    {
        get { return (data >> 17) & 0x1F; }
        set { data = (data & ~(0x1Fu << 17)) | (value & 0x1F) << 17; }
    }

    public uint month
    {
        get { return (data >> 22) & 0xF; }
        set { data = (data & ~(0xFu << 22)) | (value & 0xF) << 22; }
    }

    public uint year
    {
        get { return (data >> 26) & 0x3F; }
        set { data = (data & ~(0x3Fu << 26)) | (value & 0x3F) << 26; }
    }
}
  • 0
    en.cppreference.com/w/cpp/language/bit_field
  • 0
    Оператор% неверен, просто используйте &
Показать ещё 1 комментарий
Теги:
struct
bit-fields
marshalling

1 ответ

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

Там только одно 32-разрядное целое во всей структуре. Все различные компоненты упакованы в разные подмножества 32-битной структуры.

Вероятно, вы захотите использовать только одно поле UInt32 на стороне.NET и свойства для доступа к отдельным компонентам. Класс.NET BitVector32 может помочь вам в извлечении и обновлении битовых полей в одном 32-битном поле.

  • 0
    IIRC, как это на самом деле хранится, определяется реализацией.
  • 0
    @AK: да и нет. Реализации должны соответствовать всем битовым полям в одном DWORD. Однако порядок в этом не является стандартным.
Показать ещё 2 комментария

Ещё вопросы

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