1

我在 lua 中有一个自定义用户数据。当我tostring对用户数据的实例(在 Lua 中)执行时,它总是返回一个类似"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;
}
4

2 回答 2

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;
}
于 2012-10-08T15:45:03.947 回答
0

您将不得不覆盖tostring,以便它检查该值是否是其自定义类型之一。如果是,则使用您自己的函数来获取名称。如果没有,请将其传递给覆盖的tostring. 这通常是通过将原始tostring值放在一个上值中然后用它替换全局tostring来完成的。

于 2012-10-08T15:38:28.180 回答