【问题标题】:Lua create function with upvalues CLua创建函数与upvalues C
【发布时间】:2014-03-08 21:47:27
【问题描述】:

我正在尝试创建一个从 lua 检查时具有 2 个上值的函数。 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,我不太明白这应该如何工作。

【问题讨论】:

    标签: c lua


    【解决方案1】:

    不是很清楚你想做什么。如果你想用 2 个上值推送 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 来创建闭包。该函数的主体与创建upvalues无关,它只能通过lua_upvalueindex(n)使用它们。

    【讨论】:

      【解决方案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 创建。

      阅读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 创建一个闭包,添加到堆栈的第一个字符串是其唯一的上值;这将从堆栈中删除字符串,并将闭包放在堆栈上;然后你推送另一个字符串,并创建另一个 fvalue 闭包,这次有 2 个上值:第一个上值是创建的第一个闭包,第二个是添加的第二个字符串。我的头更晕了。希望通过 PIL 部分和我向您展示的模式有更清晰的画面。

      【讨论】:

        猜你喜欢
        • 2013-06-04
        • 1970-01-01
        • 2018-12-11
        • 1970-01-01
        • 2018-04-25
        • 2010-10-02
        • 2019-11-24
        • 2016-04-29
        • 1970-01-01
        相关资源
        最近更新 更多