lua-socket imcompatbility with Lua 5.4.3 and the fixup
source link: https://ttys3.dev/post/lua-socket-imcompatbility-with-lua-543-and-the-fixup/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
October 20, 2021
the problem⚓
lua 版本: Lua 5.4.3 Copyright (C) 1994-2021 Lua.org, PUC-Rio
相关 issue HTTP calls do not work with lua 5.4.3 #331
socket/http.lua:54: bad argument #1 to 'receive' (string expected, got light userdata)
the solution⚓
有人已经提交一个 PR 了: https://github.com/diegonehab/luasocket/pull/334
根据这个 PR 的 review comment 来看, 貌似是这个提交漏改了一处: https://github.com/diegonehab/luasocket/commit/f329aae724573b87bd2a814f4858d29ca894600b
luarocks 其实是变相地支持从 git 仓库安装 rocks 的.
不过我测试 luarocks install https://example.com/xxxx.spec
失败了, 报的是网络问题,
但是实际上我用 curl 请求是成功的, 不太清楚原因. 因此只好把 spec 文件下载回来再 install.
拿 https://github.com/diegonehab/luasocket/blob/master/rockspec/luasocket-scm-2.rockspec 修改一下:
ersion = "scm-3"
source = {
url = "git://github.com/pkulchenko/luasocket.git"
, branch="lua-543-aux-buffer-fix"
}
我把修改后的结果直接放 gist 了, 安装:
cd /tmp/ && curl -LO https://gist.github.com/ttys3/31dbf88ee7d708294d8ae5b0a4954424/raw/c74afc3edc1a48c0f7e1c2c9992750301bbb74ff/luasocket-scm-3.rockspec
luarocks install ./luasocket-scm-3.rockspec
这样安装成功后, 发现还是报同样的错. 然后发现是通过 pacman 安装了 lua-socket
包, 其优先级不知道为什么居然比我的 luarocks 的要高.
简单处理, 把系统的先卸载了吧, 看上去没啥其它东西依赖它:
❯ ls /usr/lib/lua/5.4/socket
core.so serial.so unix.so
❯ paru -R lua-socket
checking dependencies...
error: failed to prepare transaction (could not satisfy dependencies)
:: removing lua-socket breaks dependency 'lua-socket' required by lua-copas
:: removing lua-socket breaks dependency 'lua-socket' required by lua-sec
☸ homenas (tkn-demo) in ~/.luarocks via v5.4.3
🔴 1 ❯ paru -R lua-socket lua-sec lua-copas
checking dependencies...
:: luarocks optionally requires lua-sec: HTTPS support
Package (3) Old Version Net Change
lua-copas 2.0.2-3 -0.10 MiB
lua-sec 2:1.0.2-1 -0.19 MiB
lua-socket 20200329-1 -0.23 MiB
Total Removed Size: 0.52 MiB
暂时来说, 问题解决. 等 https://github.com/diegonehab/luasocket 发新版本修复.
what is Light Userdata ?⚓
https://www.lua.org/pil/28.5.html
https://www.shouce.ren/api/lua/5/_161.htm
目前为止我们使用的userdata称为full userdata。Lua还提供了另一种userdata: light userdata。
一个light userdatum是一个表示C指针的值(也就是一个void *类型的值)。由于它是一个值,我们不能创建他们(同样的,我们也不能创建一个数字)。可以使用函数lua_pushlightuserdata将一个light userdatum入栈:
void lua_pushlightuserdata (lua_State *L, void *p);
尽管都是userdata,light userdata和full userdata有很大不同。Light userdata不是一个缓冲区,仅仅是一个指针,没有metatables。像数字一样,light userdata不需要垃圾收集器来管理她。
有些人把light userdata作为一个低代价的替代实现,来代替full userdata,但是这不是light userdata的典型应用。首先,使用light userdata你必须自己管理内存,因为他们和垃圾收集器无关。第二,尽管从名字上看有轻重之分,但full userdata实现的代价也并不大,比较而言,他只是在分配给定大小的内存时候,有一点点额外的代价。
Light userdata真正的用处在于可以表示不同类型的对象。当full userdata是一个对象的时候,它等于对象自身;另一方面,light userdata表示的是一个指向对象的指针,同样的,它等于指针指向的任何类型的userdata。所以,我们在Lua中使用light userdata表示C对象。
看一个典型的例子,假定我们要实现:Lua和窗口系统的绑定。这种情况下,我们使用full userdata表示窗口(每一个userdatum可以包含整个窗口结构或者一个有系统创建的指向单个窗口的指针)。当在窗口有一个事件发生(比如按下鼠标),系统会根据窗口的地址调用专门的回调函数。为了将这个回调函数传递给Lua,我们必须找到表示指定窗口的userdata。为了找到这个userdata,我们可以使用一个表:索引为表示窗口地址的light userdata,值为在Lua中表示窗口的full userdata。一旦我们有了窗口的地址,我们将窗口地址作为light userdata放到栈内,并且将userdata作为表的索引存到表内。(注意这个表应该有一个weak值,否则,这些full userdata永远不会被回收掉。)
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK