Копирование структуры в байтовый массив - PullRequest
0 голосов
/ 06 февраля 2019

У меня есть 1-байтовая структура, упакованная в Pragma, в C, которую я хочу скопировать в байтовый массив для сериализации для отправки через последовательный порт.

#pragma pack(push, 1)

typedef struct {
    uint8_t ck_a;
    uint8_t ck_b;
} UBXChecksum_t ;

#pragma pack(pop)

Каков наилучший способ сериализации?это в байтовый массив, я должен просто использовать memcpy()?

void writeStructToArray(const void* inStruct,
                        const uint16_t inLenStruct,
                        uint8_t* const outArray)
{
  memcpy(outArray, inStruct, inLenStruct);
}

или лучше использовать побайтовое копирование при типизации указателей?

void writeStructToArray(const void* inStruct,
                        const uint16_t inLenStruct,
                        uint8_t* const outArray)
{
  for(uint16_t i = 0; i < inLenStruct; i++)
  {
    outArray[i] = ((uint8_t*)inStruct)[i];
  }
}

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Как прокомментировал Камил Цук, ваши два предложения почти одинаковы с некоторой возможной разницей в скорости.

Другой вариант - использовать объединение:

typedef struct {
    uint8_t ck_a;
    uint8_t ck_b;
} UBXChecksum_t ;

union convert {
    UBXChecksum_t checksum;
    char buffer[sizeof UBXChecksum_t];
};

UBXChecksum_t checksum;

union convert converter;

converter.checksum = checksum;

passArrayToSomeFunction(converter.buffer, sizeof(converter.buffer));

У вас нетскопировать данные, чтобы преобразовать их в массив.Вы можете передать указатель на структуру (при необходимости приведенную к char* или void*) и размер структуры в функцию, которая отправляет данные на последовательный порт.Пример:

typedef struct {
    uint8_t ck_a;
    uint8_t ck_b;
} UBXChecksum_t ;

int sendData(void *buf, size_t size);

UBXChecksum_t checksum;

/* ... */
int rc = sendData(&checksum, sizeof(checksum));

Все эти варианты отправляют внутреннее представление структуры в виде двоичных данных.Обычно «сериализация» понимается как способ преобразования данных в независимый от платформы формат.

Отправка двоичных структур данных работает, если принимающая система имеет тот же тип и использует тот же компилятор.Могут возникнуть проблемы, когда принимающая система использует другой порядок байтов или разные размеры типов данных.

В вашем случае у вас есть структура из двух значений uint8_t, поэтому размер является фиксированным, и порядок следования байтов не является проблемой.

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

0 голосов
/ 06 февраля 2019

memcpy () не будет учитывать отладку системы.таким образом, если Sender имеет большой порядковый номер, а получатель имеет младший, то в получателе будет иметь место конфликт для значения структурной переменной.

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

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

...