从C查询Lua用户数据类型

2024-01-01

我有一个具有特定元表类型的 Lua 用户数据对象(例如"stackoverflow.test")。从 C 代码中,我希望能够准确检查它是什么类型,并根据结果采取不同的行为。有没有一个很好用的方便功能(就像luaL_checkudata,但如果答案不是您想要的,则不会出错)让我查询用户数据的元表类型名称?如果没有,我想我需要使用lua_getmetatable,但是我有点不清楚如何确定刚刚添加到堆栈中的元表的名称。

只是为了澄清:我使用的是 Lua 5.1,其中 luaL_checkudata 的行为已更改。据我所知,在5.0中它不曾出现错误。


您始终可以在元表中存储一个标记字段,其中包含您的模块特有的轻用户数据值。

static const char *green_flavor = "green";
...
void my_setflavor(lua_State *L, void *flavor) {
  lua_pushlightuserdata(L,flavor);
  lua_pushlstring(L,"_flavor");
  lua_rawset(L,-3);
}

void my_isflavor(lua_State *L, void *flavor) {
  void *p = NULL;
  lua_pushlstring(L,"_flavor");
  lua_rawget(L,-2);
  p = lua_touserdata(L,-1);
  lua_pop(L,1);
  return p == flavor;
}

然后你可以使用my_setflavor(L,&green_flavor)将表的 _flavor 字段设置在堆栈顶部,并且my_isflavor(L,&red_flavor)测试堆栈顶部表的 _flavor 字段。

以这种方式使用,_flavor 字段只能采用可由范围内具有符号 green_flavor 的模块中的代码创建的值,并且除了检索元表本身之外,查找该字段并测试其值只需要一次表查找。请注意,变量 green_flavor 的值并不重要,因为实际仅使用其地址。

由于有多个不同的风味变量可用作标记值,因此 _flavor 字段可用于区分多个相关的元表。

综上所述,一个自然的问题是“为什么要这样做?”毕竟,元表可以轻松包含获得适当行为所需的所有信息。它可以轻松保存函数和数据,并且可以从 C 和 Lua 检索和调用这些函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从C查询Lua用户数据类型 的相关文章

随机推荐