序列化和反序列化位字段

时间:2012-02-08 22:11:41

标签: c++ serialization protocol-buffers boost-serialization

我已经递交了一份文件,该文件定义了一组通过串行通信渠道传输和接收的消息。我想将传入的消息和反序列化为对象,并序列化我的出站消息。线路上的编码是建立的并且不可更改,并且由报头中的各种位域和不同的有效载荷组成,例如,

class Message{
int msg_num : 7
int dest_addr : 4
bool SRR : 1
bool IDE : 1
int source_addr : 6
//... and so on...
}

我看了一下使用protobufs,但似乎建立了他们的varint编码方法。我也看了boost-serialization,但根据我到目前为止所读到的内容,编码是如何完成的还不完全清楚。

所以,有几个问题:

  • 我可以使用boost-serialization将我的bytestream转换为对象吗?
  • 目标是必须滚动我自己的序列化例程(维护混乱),是否有一个完成我的任务的首选机制(例如,自定义boost-serialization Archive,另一种方法我还没发现)

2 个答案:

答案 0 :(得分:1)

我认为您找不到一个易于使用的序列化程序,它将与您正在查看的自定义协议相匹配。但它看起来你拥有的原语集(int,bool + size)足够简单,能够编写自己的解码器/编码器。简单地根据收到的消息生成C / C ++代码。生成可编辑的代码进行这样的描述应该是相当简单的任务。它应该是在编译时完成的自动生成 - 类似于protobuf / Corba正在做的事情。

示例:来自规范:

class Message{
    int msg_num : 7
    int dest_addr : 4
    bool SRR : 1
    bool IDE : 1
    int source_addr : 6
    //... and so on...
}

转换器可以编写一个类似于(抽象符号和假设MSB)的主体函数:

解码器:

m = new Message()
{
    long long val = 0
    for(int i=0; i<7; i++) {
        val <<= 8
        val += nextByte()    
    }
    m.msg_num = val
}
{
    long long val = 0
    for(int i=0; i<4; i++) {
        val <<= 8
        val += nextByte()    
    }
    m.dest_addr = val
}
{
    int val = nextByte()
    m.SRR = val
}
{
    int val = nextByte()
    m.IDE = val
}
{
    long long val = 0
    for(int i=0; i<6; i++) {
        val <<= 8
        val += nextByte()    
    }
    m.source_addr = val
}
// and so on

编码器:

{
    long long val = m.msg_num
    for(int i=0;i<7;i++) {
        writeByte(val & 0xFF)
        val >>= 8
    }
}
{
    long long val = m.dest_addr
    for(int i=0;i<4;i++) {
        writeByte(val & 0xFF)
        val >>= 8
    }
}
....

这应该非常容易生成,并且确保编码是自定义的最简单方法。

答案 1 :(得分:0)

如果您仅限于单一平台(即限制为单字节顺序),并且消息为POD类型,则可以将消息声明为primitive

否则,至少在boost.serialization的情况下,你必须编写代码,即用于序列化的例程&#39;。它支持字节顺序转换,至少

[编辑] 错了,它不是primitive,我迷失在序列化文档的深处