Портативная альтернатива для упакованных структур с гибким элементом массива

Предположим, мы писали сетевое приложение на C ++ с использованием сокетов UDP. Нам нужно было передать небольшой пакет данных, поэтому мы использовали такую ​​структуру, чтобы убедиться, что порядок байтов является сетевым:

struct [[gnu::packed]] datagram {
uint64_t timestamp;
uint8_t type;
uint32_t temperatures[60]; // whatever, just an example
uint8_t raw_data[];
};

Мы использовали GNU GCC, поэтому мы воспользовались нестандартными функциями C ++, такими как

  • член гибкого массива
  • упакованная структура

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

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

Возможно ли это сделать в стандартном C ++?

Конечно, я знаю, что мы могли бы просто использовать uint8_t buffer[SOME_SIZE] и memcpy для каждой части дейтаграммы, но это звучит как отличный способ создать ужасный, действительно уродливый код.

0

Решение

[[gnu::packed]] это ужасный способ сделать сериализацию между произвольными архитектурами. Есть еще машины с прямым порядком байтов.

Правильный способ сделать это — определить формат сериализации в виде октетов, а затем выполнить преобразование между потоком октетов (в или из сокета UDP) и хорошо организованной структурой.

Есть много библиотек, которые делают это просто. Мы используем protobuf на работе; у предыдущего работодателя было домашнее решение. (Обратите внимание, что запрос рекомендации для такой библиотеки явно не по теме для переполнения стека.)

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]