C++/Lua FFI将userdata渲染为表格?

我有下面这段简单的C++代码,其中Object是std容器:

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);
  }
  // 处理其他索引,或抛出错误。
}

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中运行我的代码。

点赞
用户1442917
用户1442917

我不确定您所说的“可用作表”的意思,但如果您想从print(obj)的默认内容打印出不同的内容,则需要分配[__tostring元方法](https://www.lua.org/pil/13.3.html )并从其中返回一些字符串。 如果您希望该字符串看起来像“userdata:0x12345678 = {foo = 123}”,那么您可以这样做(或仅仅使用“{foo = 123}”)。

如果您的意思是使它在分配新索引时像表格一样工作,则应使用[__newindex元方法](https://www.lua.org/pil/13.4.2.html)。

2017-11-22 05:41:05