Lua:给自定义userdata一个tostring方法

时间:2012-10-08 15:08:28

标签: c++ lua tostring

我在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;
}

2 个答案:

答案 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替换为该值来完成的。