Protobuf Lua 版本 和 C#版本序列化数据不一致

论坛 期权论坛 脚本     
匿名网站用户   2020-12-20 23:16   84   0

使用 protoc-gen-lua 把protobuf 嵌入到项目中,项目中原来使用的是 Unity版本的protobuf ,需要并存,所以测试 protobuf 在两个平台序列化出来的数据是否一致。


对比发现 Lua 红的数据总是会比 C#中的数据多一点


但是最奇怪的是,虽然数据不一致,但是 lua 中序列化出来的数据,在C# 中能够正常的反序列化出来!!!


睡一晚上,再来测试


终于发现是 Lua 中对 空字符串的处理 和 C# 中不一致,而且 仅仅是对 Optional 标签的 空字符串处理不一致,对 required 标记的空字符串处理没有问题。


详解

这是我的 message

message SMsgLoginServer_Login_req
{
 required string userName = 1;
 required string password = 2;
 required int32 regionID = 3;
 optional string chanel   = 4;
 optional string token    = 5;
}

看到 userName 和 password 是 required ,然后 channel 和 token 是 Optional 的。

下面分别做实验,分别对比 userName 是空字符 的条件下 和 channel 是空字符的条件下 ,lua和C# 序列化出来的数据 。


1、required userName是空字符的条件下

Lua 版

function encoder()
    print(Login_pb.CMD_SMsgLoginServer_Login_req)
    local content=Login_pb.SMsgLoginServer_Login_req()
    content.userName=''
    content.password=''
    content.regionID=2
    --content.chanel=""
    --content.token=""
    local pb_data = content:SerializeToString()
    TestProtol.data = pb_data
end

C# 版

Login.SMsgLoginServer_Login_req content = new Login.SMsgLoginServer_Login_req();
        content.userName = "";
        content.password = "";
        content.regionID = 2;
        //content.chanel = "";
        //content.token = "";
        // ProtoBuf序列化
        byte[] bs = null;
        using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
        {
            ProtoBuf.Serializer.Serialize(ms, content);
            bs = ms.ToArray();
        }

序列化出来的数据,是一样的


2、Optional chanel 是空的条件下

Lua版

function encoder()
    print(Login_pb.CMD_SMsgLoginServer_Login_req)
    local content=Login_pb.SMsgLoginServer_Login_req()
    content.userName=''
    content.password=''
    content.regionID=2
    content.chanel=""
    --content.token=""
    local pb_data = content:SerializeToString()
    TestProtol.data = pb_data
end

C#版

 Login.SMsgLoginServer_Login_req content = new Login.SMsgLoginServer_Login_req();
        content.userName = "";
        content.password = "";
        content.regionID = 2;
        content.chanel = "";
        //content.token = "";
        // ProtoBuf序列化
        byte[] bs = null;
        using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
        {
            ProtoBuf.Serializer.Serialize(ms, content);
            bs = ms.ToArray();
        }

两者序列化出来的数据


可以看到 lua版本多了 34 0


然后我们再把 Optional channel 不设置为 空字符,随便给个字符串再来对比

Lua版

function encoder()
    print(Login_pb.CMD_SMsgLoginServer_Login_req)
    local content=Login_pb.SMsgLoginServer_Login_req()
    content.userName=''
    content.password=''
    content.regionID=2
    content.chanel="91"
    --content.token=""
    local pb_data = content:SerializeToString()
    TestProtol.data = pb_data
end

C#版

Login.SMsgLoginServer_Login_req content = new Login.SMsgLoginServer_Login_req();
        content.userName = "";
        content.password = "";
        content.regionID = 2;
        content.chanel = "91";
        //content.token = "";
        // ProtoBuf序列化
        byte[] bs = null;
        using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
        {
            ProtoBuf.Serializer.Serialize(ms, content);
            bs = ms.ToArray();
        }


序列化出来的数据


是一致的。


所以:

protoc-gen-lua 和 protobuf C# 版本对 Optional 的空字符处理不同,但是并不影响反序列化。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP