Я пишу декодер для бинарного протокола (протокол Javad GRIL). Он состоит из примерно сотни сообщений с данными в следующем формате:
struct MsgData {
uint8_t num;
float x, y, z;
uint8_t elevation;
...
};
Поля представляют собой двоичные числа в кодировке ANSI, которые следуют друг за другом без пробелов. Самый простой способ разобрать такие сообщения - привести входной массив байтов к соответствующему типу. Проблема в том, что данные в потоке упакованы, то есть не выровнены.
На x86 это можно решить с помощью #pragma pack (1)
. Однако это не будет работать на некоторых других платформах или приведет к накладным расходам производительности из-за дальнейшей работы с несовпадающими данными.
Другой способ - написать определенную функцию синтаксического анализа для каждого типа сообщения, но, как я уже упоминал, протокол включает сотни сообщений.
Еще одна альтернатива - использовать что-то вроде функции Perl unpack ()
и где-нибудь сохранить формат сообщения. Скажем, мы можем #define MsgDataFormat "CfffC"
, а затем вызвать unpack (pMsgBody, MsgDataFormat)
. Это намного короче, но все же подвержено ошибкам и избыточно. Более того, формат может быть более сложным, поскольку сообщения могут содержать массивы, поэтому синтаксический анализатор будет медленным и сложным.
Есть ли какое-нибудь общее и эффективное решение? Я прочитал этот пост и искал в Google, но не нашел лучшего способа сделать это.
Может быть, у C ++ есть решение?