在我的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代码,以便我可以为它添加更多功能?
答案 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);