使用protobuf-net发布反序列化(protocolBuffer)序列化数据

时间:2013-05-09 23:57:45

标签: c# c++ protocol-buffers protobuf-net

我使用protobuf-net对数据进行了序列化,并且能够在C#中进行相同的处理。

放一个C#dummy w#

var file = File.Create("animal.bin");
//Creating Msg - Fill the Data
animal.id = "1";
animal.Name = "Rat";
animal.host = "Cheetha";
ProtoBuf.Serializer.SerializeWithLengthPrefix(file, animal, PrefixStyle.Base128, 1);
animal.id = "2";
animal.Name = "Cat";
animal.host = "Cheetha";
ProtoBuf.Serializer.SerializeWithLengthPrefix(file, animal, PrefixStyle.Base128, 1);
....
animal.id = "4";
animal.name = "Cheetha";
animal.host = "Cheetha";
ProtoBuf.Serializer.SerializeWithLengthPrefix(file, animal, PrefixStyle.Base128, 1);
//Done Creating Msg
file.Close();

到目前为止一切都很好......这里没有问题。但是当我尝试使用协议缓冲区在C ++中反序列化相同时,我无法获得正确的数据

cpp code ...

GOOGLE_PROTOBUF_VERIFY_VERSION; 
string fpath = "animal.bin";

fstream input(fpath, ios::in | ios::binary);
if (!input)
{
    cerr << "failed to open " << fpath << endl;
    return false;
}
ZeroCopyInputStream *raw_in = new IstreamInputStream(&input);
CodedInputStream *coded_in = new CodedInputStream(raw_in);
google::protobuf::uint32 n;
std::string tmpStr;
animal::animalInfo animalList;

coded_in->ReadVarint32(&n);
cout << "# " << n << endl;  //output: #10
coded_in->ReadRaw(&tmpStr,n); //tmpStr shows data like >>1..Rat..Ch 
animalList.ParseFromArray(&tmpStr,1);//Not sure if this is correct usage?

我确信我犯了一个错误,但却无法理解什么是错误的......已阅读并重读了很多帖子,但没有看到什么是错的

使用Protocol Buffer2.5,protobuf-netR622,Visual Studio 2010

1 个答案:

答案 0 :(得分:0)

我认为你只是不匹配标题;长度前缀字段标题(字段1)是两个&#34; varint&#34; s; 第一个&#34; varint&#34;将始终为十进制10(10表示:字段1,长度前缀)。 第二&#34; varint&#34;告诉你下一个数据的长度。所以 - 如果你想手动解码 ,你可以拨打ReadVarint32 第二时间。我不熟悉ReadRaw,但如果第二个参数是要读取的字节数,那么它会去那里,即

coded_in->ReadVarint32(&n); // field header
// assert: n === 10
coded_in->ReadVarint32(&n); // length
coded_in->ReadRaw(&tmpStr,n);

或者,只需使用包装器对象 - 即

message animals {
    repeated animal items = 1;
}

并将其反序列化为animals 的实例 - 这使用完全相同的布局。这里唯一的区别是,它将一次性加载所有项目 - 所以如果您正在阅读非常长的流,这可能会有问题。

另一种选择是:不添加字段标题

Serializer.SerializeWithLengthPrefix(file, animal, PrefixStyle.Base128, 0);

然后你只会阅读一个&#34; varint&#34;:

coded_in->ReadVarint32(&n); // length
coded_in->ReadRaw(&tmpStr,n);