【问题标题】:C++/Lua FFI to render userdata as a table?C++/Lua FFI 将用户数据呈现为表格?
【发布时间】:2018-05-05 13:54:15
【问题描述】:

我在 C++ 中有以下简单代码,其中 Object 是一个标准容器:

static int create_an_object(lua_State* L) {
  auto obj = static_cast<Object*>(lua_newuserdata(L, sizeof(Object*)));
  *obj = another_valid_obj;

  luaL_newmetatable(L, "object_metatable");
  lua_pushcfunction(L, object_metatable_function);
  lua_setfield(L, -2, "__index");
  lua_pop(L, 1);
  return 1;
}

static int object_metatable_function(lua_State* L) {
  string index = luaL_checkstring(L, -1);
  if (index == "foo") {
    lua_pushnumber(L, 123);
  }
  // Handles other indices, or throws error.
}

lua_pushcfunction(L, create_an_object);
lua_setglobal(L, "create_an_object");

通过上面的FFI,我可以在Lua中实现Object的索引如:

local obj = create_an_object()
print(obj.foo)   -- 123

同时print(obj) 表明obj 是userdata: 0x12345678

是否可以使用一些元方法魔法,以便 obj 可以用作表格,而 print(obj.foo) 仍然打印 123?我在 Lua 5.1 中运行我的代码。

【问题讨论】:

    标签: c++ lua


    【解决方案1】:

    我不确定您所说的“可以用作表格”是什么意思,但是如果您想打印不同于 print(obj) 的默认值,那么您需要分配 __tostring metamethod 并返回一些字符串。如果你愿意,这个字符串可能看起来像 "userdata: 0x12345678 = {foo = 123}"(或者只是 "{foo = 123}")。

    如果您的意思是在为其分配新索引时使其作为表工作,则应使用__newindex metamethod

    【讨论】:

    • 我想支持这个用户数据的索引、ipair/pair迭代和getlen(#)操作。
    • 您可以使用__pairs/__ipairs 元方法(Lua 5.2+)和__len metamethod 来实现这一点。
    • 是的,我知道它在 5.2+ 中是可行的,但我只能使用 5.1 :(
    • @TangKe __pairs 不是像__index__add 那样的“原始”元方法,……它只是pairs 函数设置的约定。所以你可以包装或重新定义 pairs 来检查:function pairs( t ) local iter, st, k = next, t, nil ; local mt = getmetatable( t ) ; if mt and mt.__pairs then iter, st, k = mt.__pairs( t ) end ; return iter, st, k end 应该非常像 5.3 pairs/__pairs,我认为。
    猜你喜欢
    • 2020-08-15
    • 2016-07-02
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 2015-11-21
    相关资源
    最近更新 更多