6

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

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

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

所以,有几个问题:

  • 我可以使用 boost-serialization 将我的字节流转换为对象吗?
  • 为了不必滚动我自己的序列化例程(维护混乱),是否有完成我的任务的首选机制(例如,自定义提升序列化存档,另一种我没有发现的方法)
4

2 回答 2

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
    }
}
....

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

于 2012-02-19T00:13:04.643 回答
0

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

否则,至少在 boost.serialization 的情况下,您必须编写代码,即“序列化例程”。它至少支持字节顺序转换

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

于 2016-02-10T22:22:52.357 回答