用C++解析二进制消息.任何包含示例的lib?

Rom*_*dgz 4 c++ parsing bit-manipulation

我正在寻找在C++中解析二进制消息的任何示例库.大多数人要求读取二进制文件或在套接字中接收的数据,但我只需要解码一组二进制消息.有人提到了boost :: spirit,但我找不到合适的例子来满足我的需求.

例如:9A690C12E077033811FFDFFEF07F042C1CE0B704381​​E00B1FEFFF78004A92440

其中前8位是前同步码,接下来是6位msg ID(0到63之间的整数),接下来的212位是数据,最后24位是CRC24.

所以在这种情况下,msg 26,我必须从212个数据位获取这些数据:

  • 4位整数值
  • 4位整数值
  • 从0到63.875的9位浮点值,其中LSB为0.125
  • 4位整数值

编辑:我需要在位级操作,因此memcpy不是一个好的解决方案,因为它复制了许多字节.要获得第一个4位整数值,我应该从一个字节获得2位,从下一个字节获得另外2位,移位每一对并组成.我要求的是一种更优雅的方法来提取值,因为我有大约20种不同的消息,并希望达到一个通用的解决方案来解析它们的位级别.

等等.

你知道os可以轻松实现这个吗?

我还发现了其他使用static_cast的Q/A. 我用Google搜索,并且对于推荐这种方法的每个人,还有另一个关于端序的警告.由于我已经有了我的消息,我不知道这样的警告是否适用于我,或者只是用于套接字通信.

编辑:提升:dynamic_bitset看起来很有希望.任何使用它的帮助?

Ani*_*nge 6

如果找不到用于解析数据的通用库,请使用位域获取数据并将memcpy()转换为变量struct.请参阅链接Bitfields.这将更加简化您的应用程序.

不要忘记包装结构.

例:

#pragma pack

include "order32.h"
struct yourfields{
#if O32_HOST_ORDER == O32_BIG_ENDIAN
   unsigned int preamble:8;
   unsigned int msgid:6;
   unsigned data:212;
   unsigned crc:24;
#else
   unsigned crc:24;
   unsigned data:212;
   unsigned int msgid:6;
   unsigned int preamble:8;
#endif
}/*__attribute__((packed)) for gcc*/;
Run Code Online (Sandbox Code Playgroud)

您可以执行一些编译时检查以确定您的计算机是使用LITTLE ENDIAN还是BIG ENDIAN格式.之后将其定义为PREPROCESSOR SYMBOL ::

//order32.h

#ifndef ORDER32_H
#define ORDER32_H

#include <limits.h>
#include <stdint.h>

#if CHAR_BIT != 8
#error "unsupported char size"
#endif

enum
{
    O32_LITTLE_ENDIAN = 0x03020100ul,
    O32_BIG_ENDIAN = 0x00010203ul,
    O32_PDP_ENDIAN = 0x01000302ul
};

static const union { unsigned char bytes[4]; uint32_t value; } o32_host_order =
    { { 0, 1, 2, 3 } };

#define O32_HOST_ORDER (o32_host_order.value)

#endif
Run Code Online (Sandbox Code Playgroud)

由于由克里斯托夫编写@ 这里

使用位域及其输出的示例程序:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <memory.h>
using namespace std;

struct bitfields{
  unsigned opcode:5;
  unsigned info:3;
}__attribute__((packed));

struct bitfields opcodes;

/* info: 3bits; opcode: 5bits;*/
/* 001 10001  => 0x31*/
/* 010 10010  => 0x52*/

void set_data(unsigned char data)
{
  memcpy(&opcodes,&data,sizeof(data));
}

void print_data()
{
  cout << opcodes.opcode << ' ' << opcodes.info << endl;
}

int main(int argc, char *argv[])
{
  set_data(0x31);
  print_data(); //must print 17 1 on my little-endian machine
  set_data(0x52); 
  print_data(); //must print 18 2
  cout << sizeof(opcodes); //must print 1
  return 0;
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

2475 次

最近记录:

12 年,10 月 前