根据我使用中发现的问题,protobuf的使用需要慎重使用ParseFromString来实现反序列化的。
有兴趣深究protobuf反序列化原理的兄台可以瞅瞅序列化之后的内容,好像是如下格式
一个字节的转译字符 | member name| member value
如果有一个memory buffer,现在需要反序列化为一个类,万不可使用ParseFromString,隐藏着潜在的bug。如果buffer中有非字符内容,肯定反序列化的结果是有问题的。截断的情况是隐藏的,视buffer内容而定,最关键的一点,发生截断的时候也没有异常。其场景如下代码(错误用法)
char * buf ;
...获取内存快内容
string str = buf ;
proto.ParseFromString(str)
此时需要做如下的操作:
用memory buffer实例化stringstream对象,
调用stringstream的pubsetbuf(basebuf, length)函数将内存块填充进去,注意,此处不可以将buffer赋值给一个string对象,然后用string对象构造一个stringstream。这时候会发生截断。
看到github上面的很多人的使用都是错误的。本来想找一个epoll+protobuf的基础工程的代码的,看来这个工作还得自己去做。
其问题可以简化用以下代码描述。(错误用法)
char * buf ;
...
string str = buf ;
stringstream s(str) ;
proto.ParseFromIstream(s);
如下代码段的用法为正确用法
stringstream s;
s.rdbuf()->pubsetbuf(buf, length);
proto.ParseFromIstream(&s) ;
注意上面的length不能用strlen(buf)来获取。