c - 从 C 访问 lightuserdata

标签 c lua

我在一个资源非常有限的系统中使用 Lua 与 C 结合使用。

我正在使用的库创建了一些对其创建的对象的引用(作为指针),这对于以后访问这些对象很有用。为了向 Lua 公开该库的功能,当创建此类对象时,该引用将返回给 Lua 脚本。

用户可以根据自己的喜好存储此引用,因为这使得以后的调用非常方便。

示例案例:

ref = MyLib.createObject("some", arguments)
local ref = MyLib.createObject("some", arguments)
table_of_refs[45] = MyLib.createObject("some", arguments)
-- etc...

不幸的是,这些引用可能会在 Lua 脚本范围之外(从 C 内部)被破坏。因此,这些引用可能会变得无效。

目前,我的代码可以毫无问题地处理这些无效引用。所有这些指针在库中实际使用之前都会经过验证,因此代码是安全的。

然而,从 Lua 用户的角度来看,这似乎有点令人困惑,因为无法判断该引用是否仍然有效(这不是很重要,但我仍然想改进它).

我想要的是以下内容。我想从 C 迭代 Lua 存储的所有 lightuserdata。如果 lightuserdatum 不再有效,请将其设置为零。这样,下次使用时该变量将有效或为零,为用户提供更好的 API。

有什么办法可以实现这一点吗?我可以从 C all Lua 知道的 lightuserdata 中迭代(无论它们存储在哪里,本地/全局/表等),并修改它们吗?

最佳答案

没有办法从 C 访问局部 lua 变量。因此,即使您确实迭代了某种类型的 lua 对象,您也无法访问至少一个区域(局部变量)。

您可以迭代全局表中的所有内容,如 Max 的回答所示:Loop through all Lua global variables in C++

如果您要针对 lua_islightuserdata 进行测试,然后将 lightuserdata 的值与您要删除的指针进行比较,您应该能够识别出您想要的全局值。

lua_pushglobaltable(L); 
lua_pushnil(L);    
while (lua_next(L,-2) != 0) 
{
    if (lua_islightuserdata(L, -1))
    {
        //TODO: compare against the lightuserdata pointer value you are looking for
        void* mypointer = lua_touserdata(state, -1);

        name = lua_tostring(L,-2);  // Get key(-2) name
        //TODO: do whatever with the value; probably set to nil by name in the global table
    }
    lua_pop(L,1);
}
lua_pop(L,1); 

但是,如果您想在表中搜索它,则必须对 lua_istable 进行额外检查,然后以相同的方式递归迭代表的值。

...
else if (lua_istable(L, -1)
{
    //TODO: iterate each value in the table searching for lightuserdata
    // or tables with further levels of recursion
}
...

但是,我认为在 MyLib 上提供一个名为“isValid”的方法会更直接,该方法在使用该值之前返回该值是否仍然有效。

local ref = MyLib.createObject("some", arguments)
...
local isvalid = MyLib.isValid(ref)

那么您就不会受到本地范围的限制。另外,假设你无论如何都会在你的 lua 代码中进行 nil 检查(看看值是否从你的下面改变了),这在代码方面基本上不需要任何成本。

关于c - 从 C 访问 lightuserdata,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55458114/

相关文章:

c - gcc-8 Wstringop-截断

reflection - 快速确定变量是否为函数的方法?

lua - (错误)ERR错误编译脚本(新功能):user_script:2: '='附近应为 'local'

c - 加载dll时Lua段错误

c - 如何引用在 .h 文件中初始化的二维数组并在 .c 函数中使用它?

c - Do..while 内部开关

c - 引用的库函数不调用会被链接吗?

c - LLDB 调试器步骤解析

lua - 分发 Lua 和库的最佳方式是什么?

lua:为什么我不能使用包的名称?