|
使用 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 的空字符处理不同,但是并不影响反序列化。
|