Lua 5.2 中 luaL_openlib 的替代方法

26
1个回答

37

对于这个问题有两个答案:一个是为了复制早期版本的行为(其中创建了一个全局表),另一个是为了实现现在通常的行为(即创建并返回匿名表)。

针对前者:

lua_newtable(L);
luaL_setfuncs(L, polycoreLib, 0);
lua_setglobal(L, "Polycore");

这与luaL_openlib不完全相同,因为如果存在一个名为Polycore的全局表,则会覆盖它而不是合并。如果担心合并问题,请先使用lua_getglobal,然后如果它推送了一个表,请重复使用它而不是创建一个新表:

lua_getglobal(L, "Polycore");
if (lua_isnil(L, -1)) {
  lua_pop(L, 1);
  lua_newtable(L);
}
luaL_setfuncs(L, polycoreLib, 0);
lua_setglobal(L, "Polycore");

后者更容易,因为您不需要考虑合并:

lua_newtable(L);
luaL_setfuncs(L, polycoreLib, 0);
return 1;

使用这种方法,绑定表的责任在调用者身上,例如:

local Polycore = require "Polycore"

所以我有多个对象,它们正在将自己的函数调用添加到全局库中。试图在5.3中弄清楚如何做这件事总是让我回到这个答案,但是这个答案对我来说信息不足。第一个代码块会覆盖先前的条目。固定方法会在lua_getglobal()调用上引发nil引用问题,而且我不明白最后一个方法如何进行任何查找或绑定到名称“Ploycore”。我错过了什么? - James
此外,结尾处的return 1让人感觉它应该在luaopen_Polycore()调用中使用...我能否在luaL_newlib()调用后安全地在其中创建我的元表?(我之前gettop()调用出现了错误)。 (而luaL_newlib()是lua_newtable()和luaL_setfuncs()调用的包装器..有点类似) - James
3
luaL_setfuncs函数使用栈顶的表进行操作。因此,将现有表与之合并只需要将该表放到栈顶,而不是使用一个新的表。如果已经可以通过全局名称获取该表,则其仍可通过全局名称获取。显然,您无法合并具有相同键的表。如果您需要这样做(或子表),则需要手动处理。 (对于子表很容易,只需创建一个新表并将其插入到获取的表中即可。) - Etan Reisner
2
是的,在luaopen_Polycore调用中,您可以做任何需要的事情,只需在最后正确获取堆栈即可。可能更有意义的是,提出一个新问题,引用这个问题并添加lua 5.3位和您的额外目标,并展示您尝试过的代码,而不是对已回答的问题进行悬赏(因为对此的新回答不一定会回答最初提出的问题)。 - Etan Reisner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接