我在lua中有一个自定义用户数据。当我在userdata的实例(Lua内部)上执行tostring
时,它总是返回一个像"userdata: 0xaddress"
这样的字符串。我希望它返回userdata("Point: 0xaddress"
)的名称,这意味着我想覆盖tostring
以包含我的userdata的大小写。有谁知道这是否可以做到?
#define check_point(L) \
(Point**)luaL_checkudata(L,1,"Point")
static int
luaw_point_getx(lua_State* L)
{
Point** point_ud = check_point(L);
lua_pushinteger(L, (*point_ud)->x);
return 1;
}
static int
luaw_point_gety(lua_State* L)
{
Point** point_ud = check_point(L);
lua_pushinteger(L, (*point_ud)->y);
return 1;
}
void
luaw_point_push(lua_State* L, Point* point)
{
Point** point_ud = (Point**)lua_newuserdata(L, sizeof(Point*));
*point_ud = point;
luaL_getmetatable(L, "Point");
lua_setmetatable(L, -2);
}
static const struct luaL_Reg luaw_point_m [] = {
{"x", luaw_point_getx},
{"y", luaw_point_gety},
{NULL, NULL}
};
int
luaopen_wpoint(lua_State* L)
{
luaL_newmetatable(L, "WEAVE.Point");
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
luaL_register(L, NULL, luaw_point_m);
return 1;
}
答案 0 :(得分:4)
您必须以与撰写__tostring
类似的方式提供__index
元方法。
// [...]
int luaw_point_index(lua_State* L)
{
lua_pushfstring(L, "Point: %p", lua_topointer(L, 1));
return 1;
}
int luaopen_wpoint(lua_State* L)
{
luaL_newmetatable(L, "WEAVE.Point");
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, luaw_point_index);
lua_setfield(L, -2, "__tostring");
luaL_register(L, NULL, luaw_point_m);
return 1;
}
答案 1 :(得分:0)
您必须覆盖tostring
,以便检查该值是否为其自定义类型之一。如果是,则使用您自己的函数来获取名称。如果没有,请将其传递给被覆盖的tostring
。这通常是通过将原始tostring
置于upvalue然后将全局tostring
替换为该值来完成的。