Lua使用upvalues创建函数C.

时间:2014-03-07 03:23:57

标签: c lua

我正在尝试创建一个从lua检查时有2个upvalue的函数。 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,我不太清楚它是如何工作的。

2 个答案:

答案 0 :(得分:3)

不清楚你要做什么。如果你想用两个upvalues推C-closure 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来创建Closure。该函数的主体与upvalues的创建无关,它只能通过lua_upvalueindex(n)使用它们。

答案 1 :(得分:2)

模式类似于:

int fvalues (lua_State *L) {
    ... get function arguments with lua_to* functions ...
    ... get upvalues with lua_getupvalue and lua_upvalueindex and lua_to* functions ...
    ... use arguments and upvalues ...
}

int callFValues(lua_State *L) {
    const char* cstr = "This_is_a_test";
    // push two values that will be upvalues of fvalues
    lua_pushstring(L, cstr);
    lua_pushstring(L, cstr);
    // create closure using the two upvalues:
    lua_pushcclosure(L, &fvalues, 2);
    // call it: 
    lua_pcall(L, 0,0,0);
    return 1; 
}

然后注册callFValues。如果你想返回一个闭包(在Lua脚本中很常见),供Lua脚本使用,几乎相同:

int createClosure(lua_State *L) {
    const char* cstr = "This_is_a_test";
    // push two values that will be upvalues of fvalues
    lua_pushstring(L, cstr);
    lua_pushstring(L, cstr);
    // create closure using the two upvalues:
    lua_pushcclosure(L, &fvalues, 2);
    return 1; // return it to caller
}

然后注册createClosure,从脚本中调用fval = createClosure(),然后fvalfvalues的关闭,其中createClosure创建了两个upvalues。

阅读section 27.3.3 of PIL了解详细示例。但是在你的代码中,你的fvalues,你想要关闭和调用的lua_CFunction,本身就是在创建一个自己的闭包,这让我头晕目眩:)另外,

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

为fvalues创建一个闭包,第一个字符串被添加到堆栈中,它是一个唯一的upvalue;这将从堆栈中删除字符串,并将闭包放在堆栈上;然后你推另一个字符串,并创建另一个fvalues闭包,这次有2个upvalues:第一个upvalue是第一个创建的闭包,第二个是第二个添加的字符串。我的头旋得更厉害。希望通过PIL部分和我展示的模式你有更清晰的画面。