菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
378
0

Lua-pb 升级到Lua5.3

原创
05/13 14:22
阅读数 20189

项目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)

发表评论

0/200
378 点赞
0 评论
收藏