简体   繁体   English

如何在C ++中读取.proto格式的二进制文件?

[英]How do I read a .proto formatted binary file in C++?

I have a .bin file created using C# with a protobuf library and the following class: 我有一个使用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; }
}

The associated .proto file looks like 关联的.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;
}

Which has been parsed through protoc.exe to produce TextureAtlasSettings.pb.cc and TextureAtlasSettings.pb.h. 已通过protoc.exe解析,以生成TextureAtlasSettings.pb.cc和TextureAtlasSettings.pb.h。 for C++. 对于C ++。

I would like to read the resultant binary file in C++, so I tried the following code 我想用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;
}

The code above will always trigger the printf. 上面的代码将始终触发printf。 How do I go about reading the file correctly so it may be deserialized? 如何正确读取文件以便反序列化?

The model you show actually represents, to protobuf-net, optional fields (several with a default of zero). 您显示的模型实际上代表protobuf-net, 可选字段(几个默认值为零)。 Consequently, any zeros might be omitted, which would cause the c++ reader to reject the message (since your .proto lists it as required). 因此,可能会省略任何零,这会导致c ++读取器拒绝该消息(因为.proto会根据需要列出它)。

To get the representative .proto: 要获得代表.proto:

string proto = Serializer.GetProto<YourType>();

Or to make them "required" in the c#: 或者在c#中使它们“必需”:

[ProtoMember(3, IsRequired = true)]

(etc) (等等)

It should be sufficient to do this: 这样做应该足够了:

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");
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM