2013-05-09 87 views
1

我使用protobuf-net序列化数据,并且能够在C#中使用相同的数据。问题使用protobuf-net反序列化(protocolBuffer)序列化数据

把一个C#假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的代码...

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? 

我肯定我犯了一个错误,但不能要了解什么是错....已经阅读并重读很多职位上这一点,但没有看到什么还是错的

使用协议Buffer2.5,protobuf的-netR622,Visual Studio 2010中

回答

0

我认为你只是不匹配头文件;长度前缀字段头(字段1)是两个“varint”s; 第一个“varint”将始终为十进制10(10表示:字段1,长度为前缀)。 第二个“varint”告诉你下一个数据的长度。所以 - 如果你想解码它手动你会叫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); 

那么你就只能读取一个 “varint”:

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

感谢您的答复马克!你能说一下从C++的protocbuf-net序列化数据中读取1 msg @的标准/推荐方式吗?我现在可以使用下面的'coded_in-> ReadVarint32(&n); COUT << “#”,以获得正确的数据<< n <<在ENDL; //输出:#10 coded_in-> ReadVarint32(&n); COUT < <“Num Bytes#”<< n << endl; //输出:#10 coded_in-> ReadString(&tmpStr,n); animalList.ParseFromString(tmpStr);' – Vic 2013-05-10 17:14:43

+0

@Vic well ...是否有效? – 2013-05-10 18:04:18

+0

它确实,谢谢..我想知道什么是建议的方式来提取1 msg @在协议缓冲C++。我可以使用我的计划上面标记,但猜测更好的n直接的方式已经提供 – Vic 2013-05-10 18:50:06