我有一个使用C#创建的.bin文件,带有protobuf库和以下类:
[ProtoContract]
class TextureAtlasEntry
{
[ProtoMember(1)]
public int Height { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
[ProtoMember(3)]
public int Width { get; set; }
[ProtoMember(4)]
public int X { get; set; }
[ProtoMember(5)]
public int Y { get; set; }
}
关联的.proto文件看起来像
package TextureAtlasSettings; // Namespace equivalent
message TextureAtlasEntry
{
required int32 Height = 1;
required string Name = 2;
required int32 Width = 3;
required int32 X = 4;
required int32 Y = 5;
}
已通过protoc.exe解析生成TextureAtlasSettings.pb.cc和TextureAtlasSettings.pb.h。对于C ++。
我想用C ++读取生成的二进制文件,所以我尝试了以下代码
TextureAtlasSettings::TextureAtlasEntry taSettings;
ifstream::pos_type size;
char *memblock;
ifstream file("Content\\Protobuf\\TextureAtlas0.bin", ios::in | ios::binary);
if (file.is_open())
{
size = file.tellg();
memblock = new char[size];
file.seekg(0, ios::beg);
file.read(memblock, size);
file.close();
fstream input(&memblock[0], ios::in | ios::binary);
if (!taSettings.ParseFromIstream(&file))
{
printf("Failed to parse TextureAtlasEntry");
}
delete[] memblock;
}
上面的代码将始终触发printf。如何正确读取文件以便反序列化?
答案 0 :(得分:3)
您展示的模型实际上代表protobuf-net,可选字段(其中几个默认值为零)。因此,可能会省略任何零,这会导致c ++读取器拒绝该消息(因为.proto会根据需要将其列出)。
获取代表.proto:
string proto = Serializer.GetProto<YourType>();
或者在c#中使它们“必需”:
[ProtoMember(3, IsRequired = true)]
(等)
答案 1 :(得分:1)
这样做应该足够了:
TextureAtlasSettings::TextureAtlasEntry taSettings;
ifstream file("Content\\Protobuf\\TextureAtlas0.bin", ios::in | ios::binary);
if (file.is_open())
{
if (!taSettings.ParseFromIstream(&file))
{
printf("Failed to parse TextureAtlasEntry");
}
}