引用metatable从Lua 5.1.5创建的C语言

时间:2013-05-16 14:51:29

标签: lua

在我的C中,我创建了一个全局元表:

luaL_newmetatable(L, "WebSocketClient");
lua_pushliteral(L, "close");
lua_pushcfunction(L, lws_sock_close);
lua_rawset(L, -3);
lua_pop(L, 1);

但是在我的Lua中我无法添加一个函数:

function WebSocketClient:read_frame()
   --foo
end

我收到此错误:

attempt to index local 'WebSocketClient' (a nil value)

如何使这个元表可用于我的Lua代码,以便我可以为它添加更多功能?

2 个答案:

答案 0 :(得分:5)

扩展Bartek的评论(这是正确的,虽然简短):如果你想从Lua向metatable添加新函数,你需要将该表暴露给Lua。 luaL_newmetatable将您的WebSocketClient元表存储在Registry中,只能通过C(调试API中的debug.getregistry之外)访问,在沙箱Lua代码时可以删除它。

你最好创建一个普通的表,通过C库的表导出它,然后使用luaL_setmetatable(来自C)或setmetatable(来自Lua) - 将注册表视为一个放置的地方C模块内部的值。

你使用luaL_newmetatable的方式定义了一个metatable,出于安全原因,它明确地不应该从Lua访问,因此,例如Lua脚本最终用户不能搞乱核心类型的metatable。在其他情况下很有用,但不是你想要的。

答案 1 :(得分:2)

根据@ silentbicycle的答案提供代码:

lua_newtable(L);
lua_pushliteral(L, "close");
lua_pushcfunction(L, lws_sock_close);
lua_rawset(L, -3);
lua_setglobal(L, "WebSocketClient");

作为参考,您可以设置metatable:

lua_newtable(L);
lua_newtable(L);
lua_pushliteral(L, "__index");
lua_getglobal(L, "WebSocketClient");
lua_settable(L, -3);
lua_setmetatable(L, -2);
lua_settable(L, -3);