Lua创建带有upvalues的函数C。

我正在尝试创建一个具有2个upvalue的函数,当从lua中检查时,debug.getinfo(fvalues)。nups应该为2。

static int fvalues(lua_State *L) {
    int n = lua_gettop(L);
    if (str.size() == 0) {
        str = "This_is_a_test";
    }
    const char *cstr = str.c_str();
    lua_pushstring(L, cstr);
    lua_pushcclosure(L, &fvalues, 1);
    lua_pushstring(L, cstr);
    lua_pushcclosure(L, &fvalues, 2);
    lua_pushstring(L, cstr);
    return 1;
}

在这种情况下,pushclosure不应该创建一个upvalue吗?我不太了解这是如何工作的。

点赞
用户869951
用户869951

以下是代码:

int fvalues (lua_State *L) {
    ... 使用 lua_to* 函数获取参数 ...
    ... 使用 lua_getupvalue 和 lua_upvalueindex 和 lua_to* 函数获取 upvalue ...
    ... 使用参数和 upvalue ...
}

int callFValues(lua_State *L) {
    const char* cstr = "This_is_a_test";
    // 推送两个值,将成为 fvalues 的 upvalue
    lua_pushstring(L, cstr);
    lua_pushstring(L, cstr);
    // 使用两个 upvalue 创建闭包:
    lua_pushcclosure(L, &fvalues, 2);
    // 调用它:
    lua_pcall(L, 0,0,0);
    return 1;
}

然后注册 callFValues。如果想返回一个闭包(常用于 Lua 脚本),供 Lua 脚本使用,可以使用以下代码:

int createClosure(lua_State *L) {
    const char* cstr = "This_is_a_test";
    // 推送两个值,将作为 fvalues 的 upvalue
    lua_pushstring(L, cstr);
    lua_pushstring(L, cstr);
    // 使用两个 upvalue 创建闭包:
    lua_pushcclosure(L, &fvalues, 2);
    return 1; // 返回给调用者
}

然后注册 createClosure,从脚本调用它作为 fval = createClosure(),然后 fval 就是 createClosure 创建的带有两个 upvalue 的 fvalues 的闭包。

阅读 PIL 第 27.3.3 节 获取详细示例。但在代码中,你想要关闭并调用的 fvalues 即为它自己创建的闭包,这让我感到很困惑:)此外,

lua_pushstring(L, cstr);
lua_pushcclosure(L, &fvalues, 1);
lua_pushstring(L, cstr);
lua_pushcclosure(L, &fvalues, 2);

fvalues 创建了一个闭包,其中第一个添加到堆栈的字符串是它的唯一 upvalue;这会从堆栈中删除字符串,并将闭包放在堆栈上;然后,您推入另一个字符串,并创建 fvalues 的另一个闭包,这次有2个 upvalue:第一个 upvalue 是第一个创建的闭包,第二个 upvalue 是第二个添加的字符串。我的头更晕了。希望有了 PIL 部分和我展示的模式,您有了更清晰的了解。

2014-03-07 04:24:36
用户3125367
用户3125367

如果你想要推送带有2个upvalue的C闭包fvalues,那么需要这样做:

int
main(int argc, char *argv[])
{
    ...
    lua_pushstring(L, "Hello, World!");
    lua_pushnumber(L, 3.14);
    lua_pushcclosure(L, fvalues, 2);
    lua_setglobal(L, "fvalues");
    ...
}

static int
fvalues(lua_State *L)
{
    printf("%s\n", lua_tostring(L, lua_upvalueindex(1)); // Hello, World!
    printf("%g\n", lua_tonumber(L, lua_upvalueindex(2)); // 3.14
    return 0;
}

通过将lua_CFunction和栈顶的值传递给lua_pushcclosure,可以创建闭包。该函数体与upvalue的创建无关,它只能通过lua_upvalueindex(n)使用它们。

2014-03-08 13:47:27