【问题标题】:Lua Metatables for function call trapping用于函数调用捕获的 Lua 元表
【发布时间】:2015-11-05 06:11:20
【问题描述】:

我正在尝试使用 Lua Metatables 为一些内部 C++ 函数创建一个更漂亮的接口。

这是我目前工作的代码。 (my.get 和 my.set 是用 C++ 实现的)

function setDefault(t)
  local mt = {
  __index = function(tab,k) return my.get(t,k) end,
  __newindex = function(tab,k,v) return my.set(t,k,v) end
  }
  _G[t] = {}
  setmetatable(_G[t],mt)
end

setDefault("LABEL")

LABEL.Text = "wibble" -- evaluates as my.set("LABEL","Text","wibble")
foo = LABEL.Text -- foo = my.get("LABEL","Text")

到目前为止还不错。下一点我想要做的是桌子上的函数调用,像这样:

LABEL.Flash(500) --must evaluate my.execute("LABEL","Flash", 500)

我知道这会调用 my.get("LABEL","Flash") — 我可以让它返回一个 C++ 函数(使用 lua_pushcfunction),但是当调用 C++ 函数时,它缺少 LABEL 和 Flash 参数。

这是my.get 的 C++ sn-p。

static int myGet(lua_State * l)
{
  std::string p1(luaGetString(l, 1)); // table
  std::string p2(luaGetString(l, 2)); // 'method'

  if (isMethod(p1,p2))
  {
    lua_pushcfunction(l, myExec);
    lua_pushvalue(l, 1); // re-push table
    lua_pushvalue(l, 2); // re-push method
    return 3;
  }
  else
  {
  // do my.get stuff here.
  }
}

【问题讨论】:

    标签: c++ lua metatable


    【解决方案1】:

    稍作改动,我就有了一些可行的方法:推送一个 C closure 而不是 C function。

      if (isMethod(p1,p2))
      {
        lua_pushvalue(l, 1); // re-push table
        lua_pushvalue(l, 2); // re-push method
        lua_pushcclosure(l, myExecClosure,2);
        return 1;
      }
    

    myExecClosure 类似于 myExec,但它通过上值(例如 luaupvaluindex(1))而不是从堆栈索引 1 和 2 读取前两个参数。

    【讨论】:

      猜你喜欢
      • 2013-07-14
      • 2023-03-24
      • 1970-01-01
      • 2015-03-08
      • 1970-01-01
      • 1970-01-01
      • 2012-06-29
      • 2021-04-15
      • 2023-03-27
      相关资源
      最近更新 更多