D: (Win32) lua_rawgeti() 推送 nil

D: (Win32) lua_rawgeti() pushes nil

我正在调查一个奇怪的问题:在 Windows 上,lua_rawgeti() 没有 return 返回我创建引用的值,而是一个 nil。代码:

lua_State *L = luaL_newstate();
luaL_requiref(L, "_G", luaopen_base, 1);
lua_pop(L, 1);

lua_getglobal(L, toStringz("_G"));
int t1 = lua_type(L, -1);
auto r = luaL_ref(L, LUA_REGISTRYINDEX);

lua_rawgeti(L, LUA_REGISTRYINDEX, r);
int t2 = lua_type(L, -1);

lua_close(L);

writefln("Ref: %d, types: %d, %d", r, t1, t2);

assert(r != LUA_REFNIL);
assert((t1 != LUA_TNIL) && (t1 == t2));

完整源代码和构建 bat:https://github.com/mkoskim/games/tree/master/tests/luaref


编译 & 运行:

rdmd -I<path>/DerelictLua/source/ -I<path>/DerelictUtil/source/ testref.d

64位Linux(_G为table,rawgeti放一个table入栈):

$ build.bat
Ref: 3, types: 5, 5

32 位 Windows(_G 是 table,但 rawgeti 将 nil 放入堆栈):

$ build.bat
Ref: 3, types: 5, 0
<assertion fail>

因此,要么 luaL_ref() 无法正确存储对 _G 的引用,要么 lua_rawgeti() 无法正确检索 _G。

更新: 我从源代码编译了 Lua 库,并将 printf() 添加到 lua_rawgeti() (lapi.c:660)打印参考文献:

printf("lua_rawgeti(%d)\n", n);

我还在 test.d 中添加了 writeln() 以告诉我我们在哪个点调用 lua_rawgeti()。说明D正确发送了参考号:

lua_rawgeti(2)
lua_rawgeti(0)
Dereferencing:
lua_rawgeti(3)
Ref: 3, types: 5, 0

在 Windows 上,我使用:

问题:

代码中是否存在我没​​有发现的错误?是否有任何已知的 "quirks" 或类似的东西可以在 Windows 上使用 32 位 D 和 Lua?我的编译器和库不会有任何大问题,因为它们编译和 link 一起没有任何错误,并且 lua 调用大部分工作(例如打开 lua 状态,将 _G 推到堆栈等)。

我在谷歌搜索时找不到任何相关内容,所以我很确定我的设置有问题(有些不匹配)。我很难怀疑 Lua 库中的问题,因为它们已经存在 table 很长时间了(甚至是 32 位版本)。

我想知道,如果人们使用 64 位 Windows DMD + Lua 成功。当然,如果有人成功使用 32 位 Windows DMD + Lua,我将不胜感激。

我不知道去哪里寻找解决方案。知道接下来要尝试什么吗?

提前致谢!

我从 lua 邮件列表中得到了答复:http://lua-users.org/lists/lua-l/2019-05/msg00076.html

I suspect this is a bug in DerelictLua.

Lua defines lua_rawgeti thus:

int lua_rawgeti (lua_State *L, int index, lua_Integer n);

While DerelictLua defines its binding thus:

alias da_lua_rawgeti = int function(lua_State*, int, int);

我修复了这个问题并向 DerelictLua 创建了拉取请求。