starwing / lua-protobuf

A Lua module to work with Google protobuf
MIT License
1.75k stars 387 forks source link

与python生成的二进制文件不兼容 #43

Closed llisper closed 6 years ago

llisper commented 6 years ago

涉及的库版本:

  1. lua-protobuf-0.2.0
  2. protobuf-3.5.1(使用proto 3格式)
  3. python-2.7.14
  4. unity 2017.3.1f1(.NET 4.6)
  5. slua-1.5.5(luajit-2.1.0-beta3) <= 编译集成lua-protobuf-0.2.0
  6. 使用protobuf-3.5.1的protoc生成python和c#代码以及FileDescriptorSet(.pb)文件

问题描述: proto文件定义如下:

syntax = "proto3";
package table;
option csharp_namespace="Table";
message example
{
    int32 int_v = 1;
    int64 long_v = 2;
    float float_v = 3;
    double double_v = 4;
    string string_v = 5;
    bool bool_v = 6;
    repeated int32 array_int = 7;
}

message example_collection
{
    string key_field = 1;
    repeated example rows = 2;
}

填充数据如下(这里我就用lua代码格式来描述了):

exampleCollection = {
    key_field = "int_v",
    rows = {
        {
            int_v = 123,
            long_v = 8589934592,
            float_v = 3.14,
            double_v = 3.1415926,
            string_v = "hello world",
            bool_v = true,
            array_int = { 1, 2, 3, 4, 5 }
        }
    }
}

使用protoc生成python代码后,使用python代码根据proto定义填充数据并编码写入文件example.bytes, protoc生成的c#代码可以解析example.bytes文件。使用protoc生成FileDescriptorSet(.pb)文件, 在lua中调用pb.load接口载入.pb文件,然后调用pb.decode解析example.bytes文件,会产生报错: type mismatch at offset 39, varint expected for type int32, got bytes 如果我使用lua-protobuf来填充相同的数据并encode写入文件example.bytes, 这个文件就可以同时被lua和c#解析成功。

gen_bytes.zip

llisper commented 6 years ago

貌似问题出在array_int这个repeated类型的值上,如果我删去array_int,那么由python生成的bytes文件使用lua-protobuf解析就没有问题了,尽管生成的二进制文件并不完全一样

llisper commented 6 years ago

pb_ecode_test.zip 这里是一个简洁的例子

llisper commented 6 years ago

知道了...因为proto3中, 对于repeated filed, 默认packed=true。我没有显式设置packed属性,于是会有上面的解析问题。我显式设置packed=true后就可以了。

starwing commented 6 years ago

现在的最新版本的proto3已经是默认packed了,你可以试试看~