1

我有一个使用 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。如何正确读取文件以便对其进行反序列化?

4

2 回答 2

3

您显示的模型实际上代表 protobuf-net 的可选字段(几个默认为零)。因此,可能会省略任何零,这将导致 c++ 阅读器拒绝该消息(因为您的 .proto 根据需要将其列出)。

获取代表 .proto:

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

或者在 c# 中使它们成为“必需”:

[ProtoMember(3, IsRequired = true)]

(ETC)

于 2012-09-08T17:06:32.173 回答
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");
    }
}
于 2012-09-08T14:33:06.730 回答