将上值传递给C语言中的Lua 5.2模块。

我正在尝试为自己创建一个实验环境,其中我的应用程序作为一个 Telnet 服务器运行,提供理论上无限的 Telnet 客户端,这些客户端可以在自己的 Lua 环境中执行 Lua 命令。为此,每个客户端都有自己的线程,因为我希望它们有自己的窗口消息循环,满足自己特定的需求。

我已经创建了几个可以在 Lua 中访问的模块来做一些有趣的事情。我也希望能够从 Lua 中创建一个窗口,因此我想添加一个名为 “window” 的模块,并添加一个 “new” 方法。问题是,我需要知道我在哪个线程中(更确切地说,我需要使用的类来定义线程正在处理的客户端),我不知道如何在 C Lua 函数中获取它,以用于 window.new

在正常函数中,您可以添加上值(我已经有了一个简单的 window 函数,它可以创建一个由它运行的线程管理的窗口),但是当创建模块时,如果尝试以标准方式执行它,这将不是那么简单。

我的窗口模块具有以下典型的 luaopen 函数:

LUALIB_API int luaopen_window (lua_State *L) {
    /* register window class */
    luaL_newmetatable(L, "window");
    luaL_setfuncs(L, reg_window_m, 0);
    /* register window function */
    luaL_newlib(L, reg_window_f);
    return 1;
}

我的线程创建了一个 Lua 状态并打开必要的库,包括窗口:

luaL_requiref(L, "window", luaopen_window, 1);
lua_pop(L, 1);

我知道函数 luaL_setfuncs 支持上值,但是在那里已经太迟了。我没有方法传递值以放入上值中。

我已尝试在调用 luaL_requiref 之前将它们推入堆栈,然后在 luaopen_window 函数内部弹出它们,在调用 luaL_setfuncs 之前再将它们推入,但是它不起作用:推入的值已经消失,因为 luaL_setfuncs 在内部的工作方式。当然,我可以编写自己的支持上值的 luaL_setfuncs(我认为我可以),但肯定存在更好的方法吧?

编辑:顺便说一下,我希望避免使用全局 Lua 变量来存储指向我的类的指针。这可能会变成安全风险,尽管这个工具可能永远不会在我的计算机之外使用,但我只是想正确编写它。

点赞
用户3677376
用户3677376

luaopen_* 函数应该被 require 函数调用,并且 require 函数不会传递额外的参数(除了模块名和文件路径)以避免当使用不同的参数进行第二次调用时返回第一次调用的缓存结果时产生的混淆。

然而,你可以在创建 Lua 状态之后将线程/类存储在注册表中(在伪索引 LUA_REGISTRYINDEX 上)。没有 debug 库,从 Lua 中无法访问注册表,因此你应该是安全的。你可以在你的 luaopen_window 函数中检索类,并将其作为上值传递给你的方法,或者从你的方法中访问注册表。

为了避免与在注册表中存储信息的其他模块发生冲突,你可以使用静态变量的地址作为表键。

2014-09-09 10:17:08