gpt4 book ai didi

c++ - 使用 luaL_ref 获取对表中用户数据的引用?

转载 作者:搜寻专家 更新时间:2023-10-31 02:05:11 30 4
gpt4 key购买 nike

首先,我很抱歉没有上传完整的代码。

我正在尝试转换 userdatapointer所以它可以使用 lua_rawgeti() 传递给其他 lua block .

如果您看到 outletRet()函数,它检查返回值的类型,如果它是 userdata ,它通过调用 outlet_pointer() 将指针传递给其他 lua block 它似乎工作正常。

如果userdatatable里面, outletTable()函数被调用。如果其中一个元素是 userdata它还转换userdatapointer然后通过调用 outlet_pointer() 将其传递给其他 block .

然而,当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();
}

最佳答案

I'm trying to convert userdata to a pointer

不要。不一样,指针不代表userdata。您不能通过指向其数据区域的指针来检索 Lua 用户数据对象。

如果您需要在 native 端操作用户数据,请使用 luaL_ref() 将用户数据保存在注册表中,并使用返回的整数作为引用。稍后您可以从注册表中检索该对象并在需要时获取指向其数据区域的指针。但不要只存储指针。

至于引用表的问题,使用luaL_ref() 保存在注册表中的对象必须在Lua 栈顶。但现在唯一留在 Lua 堆栈顶部的是表格。您复制该表的值以使用 while(lua_next()) 进行迭代,并且在该循环内从表中读取的任何内容都会在循环结束时从堆栈中弹出。

您可能根本不应该构建av 结构,而是在扫描原始表时立即处理数据。那时您不需要引用/取消引用用户数据。如果您真的必须拥有那个 av,那么请保存 luaL_ref() 返回的整数索引,而不是指向用户数据内存的指针。您应该在第一个循环中执行此操作,而不是在第二个循环中执行。然后第二个循环将执行 lua_rawgeti() 以获取 userdata 对象,处理后您可以取消引用它。

关于c++ - 使用 luaL_ref 获取对表中用户数据的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52354924/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com