Lua:查询一个userdata对象的metatable名称
2016-8-13 11:45:40
收藏:0
阅读:71
评论:1
我想查询某个对象的metatable名称。
假设我注册了一个metatable如下:
Object obj; // 一些 C 对象
luaL_newmetatable(lua, "my_metatable"); // 它是空的
lua_pushlightuserdata(lua, &obj);
luaL_setmetatable(lua, "my_metatable");
lua_setglobal(lua, "obj_");
文档 此处 表明 luaL_newmetatable 执行了双向关联,即 它把名称用作表的键并把表用作名称的键。 所以,有了这个知识,我认为我可以通过以下方式实现我的目标:
int getMTName(lua_State *L)
{
lua_getmetatable(L, 1); // 获取对象的metatable
lua_rawget(L, LUA_REGISTRYINDEX); // 由于metatable是键
// 使用它来查询名称
return 1; // 栈底现在是metatable名称
}
并像这样注册它:
lua_pushcfunction(lua, getMTName);
lua_setglobal(lua, "getMTName");
但是,不幸的是,它没有起作用,它返回了 nil。那么我做错了什么?
这里是完整的源代码(C++):
extern "C"
{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include <iostream>
struct Object {
int x;
};
int getMTName(lua_State *L)
{
lua_getmetatable(L, 1);
lua_rawget(L, LUA_REGISTRYINDEX);
return 1;
}
int main(int argc, char **argv)
{
lua_State *L =luaL_newstate();
luaL_openlibs(L);
Object obj;
lua_pushcfunction(L, getMTName);
lua_setglobal(L, "getMTName");
luaL_newmetatable(L, "my_metatable");
lua_pushlightuserdata(L, &obj);
luaL_setmetatable(L, "my_metatable");
lua_setglobal(L, "obj_");
int e = luaL_dostring(L, "print(getMTName(obj_))");
if (e)
{
std::cerr << "ERR: " << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
}
return 0;
}
输出是 nil。我的 Lua 版本是 5.3。
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 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 代码?

好的,我明白了。查看 https://www.lua.org/source/5.3/lauxlib.c.html#luaL_newmetatable 中的源代码,我注意到这种双重关联是使用元表中的 "__name" 来完成的,而不是使用表作为其名称在注册表中的键。这种行为始于 Lua 5.3。
示例代码:
extern "C" { #include <lua.h> #include <lualib.h> #include <lauxlib.h> } #include <iostream> struct Object { int x; }; int getMTName(lua_State *L) { lua_getmetatable(L, 1); lua_pushstring(L, "__name"); lua_rawget(L, 2); return 1; } int main(int argc, char **argv) { lua_State *L =luaL_newstate(); luaL_openlibs(L); Object obj; lua_pushcfunction(L, getMTName); lua_setglobal(L, "getMTName"); luaL_newmetatable(L, "my_metatable"); lua_pushlightuserdata(L, &obj); luaL_setmetatable(L, "my_metatable"); lua_setglobal(L, "obj_"); int e = luaL_dostring(L, "print(getMTName(obj_))"); if (e) { std::cerr << "ERR: " << lua_tostring(L, -1) << std::endl; lua_pop(L, 1); } return 0; }