Могу ли я использовать объединение и битовое поле для упаковки данных - PullRequest
0 голосов
/ 19 мая 2018

Я создаю 4-битную и 8-битную цветовую кодировку для шрифта.Это включает в себя передний план, фон, стиль и формат.Я надеюсь использовать следующую структуру для представления данных в 4-байтовом пакете.Мое намерение состоит в том, чтобы извлечь его как один uint32_t, который можно преобразовать в двоичные данные и сохранить в файле.

Это то, что у меня сейчас есть:

struct font_pack {
    uint8_t : 8;
    struct {
        uint8_t format : 4;
        uint8_t style : 4;
    } header;
    uint8_t foreground;
    uint8_t background;
}

Заголовок содержитдва полубайта.format говорит, что цветовые коды являются 4-битными или 8-битными.style - это набор битовых флагов, который объявляет форматер, такой как жирный шрифт и подчеркивание.

Затем я использую следующий union, чтобы получить необработанный двоичный файл как для записи в файл, так и для установки или печатиданные в шестнадцатеричном формате.

union font_raw {
    font_pack pack;
    uint32_t data;
}

К сожалению, когда я распечатываю гекс, я получаю 0x04032100, когда ожидал 0x00120304.Что заставляет меня чувствовать, что выравнивание байтов не гарантируется в течение union, и меня поразил порядок байтов.Я просто надеялся, что у меня будет простой метод упаковки и распаковки данных в 3 байта.

Есть ли другой простой способ сделать это, или я застрял в создании более традиционной функции, которая выполняет упаковку и распаковку

1 Ответ

0 голосов
/ 19 мая 2018

Это похоже на проблему с порядком байтов.Я предполагаю, что вы используете архитектуру x86 / x64 (Intel-like), которая имеет младший порядок и будет упаковывать байты от наименее значимого до наиболее значимого.При условии, что вы пишете и читаете данные в одной и той же архитектуре (например, в системах с прямым порядком байтов), порядок байтов гарантирует, что вы получите считывание байтов в обратном порядке в том же порядке, поэтому члены font_pack все равно должны отображаться правильно.Однако, если вы будете загружать эти файлы в систему с прямым порядком байтов, вам нужно пойти более традиционным путем.Но если вам гарантирован такой же порядок байтов, я бы пошел с вашим методом.Это красиво и элегантнозатем определите LITTLE_ENDIAN в вашей системе x86 или аналогичной, а не в системе с прямым порядком байтов.Надеюсь, это поможет.

...