項目lua庫升級到5.3版本后,最頭疼的就是原先的一些第三方庫原先只是基於lua5.1設計的,比如protobuff 相關的的. 之前項目引入Lua-pb 實現protobuf的解析和使用,但是這個庫對64位的數據大多是基於32位,有些地方需要修改下。
替換 Struct pack/unpack
Struct似乎不支持64位數據的,比如下面的測試,struct.unpack解壓后不會大於0xffffffff,也有可能是C庫編譯的時候有特別的設置。 反正最后替換為 Lua5.3 自帶的string.pack/string.unpack來實現數據pack/unpack
local num = 0x100010ffffffff
printf("src num %d", num) -- 1ffffffff
local packData =struct.pack('<I8', num)
local num2 = struct.unpack('<I8',packData) -- ffffffff
printf("src num %d", num2)
local stringPack = string.pack("<i8",num)
local num3 = string.unpack('<i8',stringPack)
printf("src num %d", num3) -- 1ffffffff
替換 Bit庫
Lua-pb 中bit庫是使用Luajit中的bit庫,引入Lua5.3后就不需要,使用lua5.3實現類似的操作即可,而且支持64位位操作。
What’s new in Lua 5.3 (alpha work 2) 給出了一些方案,可以作為參考。
替換bit庫的實現方案:
local bit53 = {}
bit53.band = function(a, b)
return a & b
end
bit53.bor = function(a, b)
return a | b
end
bit53.bxor = function(a, b)
return a ~ b
end
bit53.bnot = function(a)
return ~ a
end
bit53.lshift = function(a, b)
return a << b
end
bit53.rshift = function(a, b)
return a >> b
end
bit53.arshift = function(a, b)
a = a & 0xFFFFFFFF
if b <= 0 or (a & 0x80000000) == 0 then
return (a >> b) & 0xFFFFFFFF
else
return((a >> b) | ~(0xFFFFFFFF >> b)) & 0xFFFFFFFF
end
end
大數編碼
之前基於32位的版本,實現比較大的數字(64位)輸是通過轉換為字符的方式進行的,Lua5.3下 就可以不使用這種方式,例如下面的測試,message,parse后並不能還原,超過32位的部分和輸入不對應。
//pb 文件
package big_numbers;
message BigNumbers1 {
required uint64 field1 = 1;
}
//測試文件
local pb = require"pb"
-- load .proto file.
local big_nums = require"protos.big_numbers"
local Max64 = 0x1fffffffffffff
local Max32 = 0xffffffff
local BigNumbers1 = big_nums.BigNumbers1
local msg = BigNumbers1()
msg.field1 = Max64
pb.print(msg)
local bin = msg:Serialize()
print("--- decode message")
local msg1, off = assert(BigNumbers1():Parse(bin))
print(tonumber(msg1.field1))
問題:
local H3 = 0x1ffffffffffffff / 0x100000000 計算得到的結果0x2000000 而不是 0x1ffffff ,似乎是計算溢出的問題,可以這樣修改:
local l = num % 0x100000000
local h = (num - l) / 0x100000000
參考:
Bitwise operation
What’s new in Lua 5.3 (alpha work 2)
Google Protocol Buffers Encoding
Google Protocol Buffers 編碼(Encoding)