将C结构存储在Lua注册表中
当我将Lua集成到我的C程序中时,我一直在使用一个指向C结构体的static指针来存储我需要在绑定到Lua状态的方法中重用的对象。
但是,一旦我将Lua库从主程序中拆分出来,这样做就行不通了,因此似乎我需要使用注册表来存储我的结构体。
我该如何在Lua注册表中存储C结构体指针?
这是我目前正在做的事情:
`` ` 静态水晶* 8月= NULL;
static int lua_aug_get(lua_State *L) { //在这里使用aug做一些事情 / 返回结果的数量 / 返回1; }
结构lua_State * luaopen_augeas(augeas * a){ lua_State * L = luaL_newstate(); 8月= a; //这显然行不通 luaL_openlibs(L); //下面的方法将需要访问水晶*结构 //所以我需要将其推入注册表(我猜) static const luaL_Reg augfuncs [] = { {“get”,lua_aug_get}, {“label”,lua_aug_label}, {“set”,lua_aug_set}, {NULL,NULL} };
luaL_newlib(L,augfuncs);
lua_setglobal(L,“aug”);
返回L;
}
`` `
编辑:从我在IRC上得到的答案来看,似乎我应该使用metatable,因此我目前正在研究这个问题。
如果注册表不是足够安全的存储指针的地方,你可以将它作为上值推送到特定的函数中:
static int lua_aug_get(lua_State *L) {
augeas *aug = lua_touserdata(L, lua_upvalueindex(1));
// Do stuff with aug
return 1;
}
static const luaL_Reg augfuncs[] = {
{ "get", lua_aug_get },
{ "label", lua_aug_label },
{ "set", lua_aug_set },
{ NULL, NULL }
};
lua_createtable(L, 0, 0);
for (size_t i = 0; augfuncs[i].name; i++) {
lua_pushlightuserdata(L, a);
lua_pushcclosure(L, augfuncs[i].func, 1);
lua_setfield(L, -2, augfuncs[i].name);
}
但是在注册表中存储它也是可以的。它不可通过脚本访问,除 debug 库外通常不在沙箱中暴露。而且如果其他库在注册表中创建自私的混乱,你无论如何都会遇到麻烦。
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

我使用了 Lua Registry Index 并将指针作为 light userdata 推入来使其正常工作:
static const char *Key = "augeas_registry_key"; // 注册表键 static augeas *checkaug(lua_State *L) { lua_pushlightuserdata(L, (void *)&Key); // 设置注册表键 lua_gettable(L, LUA_REGISTRYINDEX); // 检索值 augeas *aug = (augeas *)lua_touserdata(L, -1); // 转换值类型 return aug; } static int lua_aug_get(lua_State *L) { augeas *aug = checkaug(L); // 使用 aug 做一些事情 return 1; } struct lua_State *luaopen_augeas(augeas *a) { lua_State *L = luaL_newstate(); luaL_openlibs(L); lua_pushlightuserdata(L, (void *)&Key); // 设置注册表键 lua_pushlightuserdata(L, (void *)a); // 推入指针 lua_settable(L, LUA_REGISTRYINDEX); // 存入注册表 static const luaL_Reg augfuncs[] = { { "get", lua_aug_get }, { "label", lua_aug_label }, { "set", lua_aug_set }, { NULL, NULL } }; luaL_newlib(L, augfuncs); lua_setglobal(L, "aug"); return L; }不过这并不是很优雅,因为它使用了共享注册表,这可能会被在会话期间加载的其他库访问,因此我仍然接受更好的选择。