【发布时间】:2019-02-20 14:55:20
【问题描述】:
首先,我很抱歉没有上传完整的代码。
我正在尝试将userdata 转换为pointer,以便可以使用lua_rawgeti() 将其传递给其他lua 块。
如果你看到 outletRet() 函数,它会检查返回值的类型,如果是 userdata,它会通过调用 outlet_pointer() 将指针传递给其他 lua 块,它似乎工作正常。
如果userdata 在table 中,则调用outletTable() 函数。如果其中一个元素是userdata,它还会将userdata 转换为pointer,然后通过调用outlet_pointer() 将其传递给其他块。
但是,当调用 luaL_ref(L, LUA_REGISTRYINDEX) 时,它似乎获得了对整个 table 的引用,而不仅仅是其中的 userdata。
如何获得对userdata 的引用而不是整个table?
void ofLua::outletTable() //called from outletRet() below
{
lua_pushvalue(L, -1);
lua_pushnil(L);
int ac = 0;
t_atom *av = static_cast<t_atom *>(getbytes(sizeof(t_atom) * ac));
while (lua_next(L, -2))
{
av = static_cast<t_atom *>(resizebytes(av, sizeof(t_atom) * ac,
sizeof(t_atom) * (ac + 1)));
if (lua_isboolean(L, -1))
{
av[ac].a_type = A_FLOAT;
av[ac].a_w.w_float = static_cast<t_float>(lua_toboolean(L, -1));
}
else if (lua_isnumber(L, -1))
{
av[ac].a_type = A_FLOAT;
av[ac].a_w.w_float = static_cast<t_float>(lua_tonumber(L, -1));
}
else if (lua_isstring(L, -1))
{
av[ac].a_type = A_SYMBOL;
av[ac].a_w.w_symbol = gensym(lua_tostring(L, -1));
}
else if (lua_isuserdata(L, -1))
{
av[ac].a_type = A_POINTER;
}
ac++;
lua_pop(L, 1);
}
lua_pop(L, 1);
const ofeliaIO &io = dataPtr->io;
if (io.hasMultiControlOutlets)
{
int last = (io.numOutlets >= ac ? ac : io.numOutlets) - 1;
for (int i = last; i >= 0; --i)
{
if (av[i].a_type == A_FLOAT)
outlet_float(io.outlets[i], av[i].a_w.w_float);
else if (av[i].a_type == A_SYMBOL)
outlet_symbol(io.outlets[i], av[i].a_w.w_symbol);
else if (av[i].a_type == A_POINTER)
{
userDataRefVec.push_back(luaL_ref(L, LUA_REGISTRYINDEX));
outlet_pointer(io.outlets[i], reinterpret_cast<t_gpointer *>(&userDataRefVec.back()));
luaL_unref(L, LUA_REGISTRYINDEX, userDataRefVec.back());
userDataRefVec.pop_back();
}
}
}
else
outlet_list(dataPtr->ob.ob_outlet, &s_list, ac, av);
freebytes(av, sizeof(t_atom) * ac);
}
void ofLua::outletRet()
{
const ofeliaIO &io = dataPtr->io;
if (!io.hasControlOutlet) return;
if (lua_isnil(L, -1))
outlet_bang(io.outlets[0]);
else if (lua_isboolean(L, -1))
outlet_float(io.outlets[0], static_cast<t_float>(lua_toboolean(L, -1)));
else if (lua_isnumber(L, -1))
outlet_float(io.outlets[0], static_cast<t_float>(lua_tonumber(L, -1)));
else if (lua_isstring(L, -1))
outlet_symbol(io.outlets[0], gensym(lua_tostring(L, -1)));
else if (lua_isuserdata(L, -1))
{
userDataRefVec.push_back(luaL_ref(L, LUA_REGISTRYINDEX));
outlet_pointer(io.outlets[0], reinterpret_cast<t_gpointer *>(&userDataRefVec.back()));
luaL_unref(L, LUA_REGISTRYINDEX, userDataRefVec.back());
userDataRefVec.pop_back();
}
else if (lua_istable(L, -1))
outletTable();
}
【问题讨论】:
-
outlet_pointer(io.outlets[0], reinterpret_cast<t_gpointer *>(&userDataRefVec.back()));这是什么? -
@IllidanS4 将
userDataRefVec的最后一个元素整数的地址传递给其他Lua 块,因此可以通过lua_rawgeti()在那里使用userData。很抱歉,我无法解释更多细节。 -
有什么理由将它作为指针传递?为什么不简单地传递整数?
-
@IllidanS4 因为我想区分
number和userdata,所以它们不会冲突。
标签: c++ lua lua-userdata