c++ - Lua 用户数据指针的生命周期

标签 c++ lua lua-userdata

如果我创建一个 userdata 对象并将其存储在表中,然后在 C/C++ 中获取对它的引用,该引用的有效期为多长时间?只要用户数据保存在 Lua 中的表中,C/C++ 中的引用是否保证有效?或者是否存在 Lua 运行时将移动 userdata 对象,从而使对其的 C/C++ 引用无效的风险?

这是我正在做的:

// Initially, the stack contains a table
class Foo { ... };
lua_pushstring(L, "my_userdata");
void* mem = lua_newuserdata(L, sizeof(Foo));
new (mem) Foo();
lua_settable(L, -3);

// Later:
lua_pushstring(L, "my_userdata");
lua_gettable(L, -2);
Foo *foo = (Foo*)lua_touserdata(L, -1);
lua_pop(L, 1);
// How long will this pointer be valid?

我是否最好在这里使用 operator new 和少量用户数据?

最佳答案

引用(或指针,因为 Lua 是用 C 编写的)将在用户数据的生命周期内保持有效。

Lua 的首席架构师在 Lua-l mailing list 上解决了这个问题:

Quote: Apr 18, 2006; Roberto Ierusalimschy

The caution is about strings, not about userdata (although we actually did not say that explicitly in the manual). We have no intention of allowing userdata addresses to change during GC. Unlike strings, which are an internal data in Lua, the only purpose of userdata is to be used by C code, which prefer that things stay where they are :)

您可以通过将用户数据锚定在以下状态来控制其生命周期:

您可能更喜欢完整用户数据而不是轻量级用户数据的原因有以下几个:

  • 完整的用户数据可能有自己的用户值和元表(所有轻型用户数据共享同一个元表)
  • 通过 __gc 元方法完成
  • 一些用于处理用户数据的便捷 API 函数(luaL_newmetatableluaL_setmetatable 等)

在 C++ 中从类创建用户数据的常用方法是使用 pointer-to-pointer idiom :

class Foo { ... };

static int new_Foo(lua_State *L) {
    // begin userdata lifetime
    Foo **ud = static_cast<Foo **>(lua_newuserdata(L, sizeof *ud)); 
    luaL_setmetatable(L, "Foo");

    // begin C++ object lifetime  
    *ud = new Foo();
    return 1;
}

// __gc metamethod
static int delete_Foo(lua_State *L) {  
    Foo **ud = static_cast<Foo **>(luaL_checkudata(L, 1, "Foo"));

    // end C++ object lifetime
    delete *ud;

    // end userdata lifetime
    return 0;
}

关于c++ - Lua 用户数据指针的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38718475/

相关文章:

performance - 使张量中的值符合给定范围

Lua 代码 "tester"

java - LuaJ 数组/列表类型安全

c - Lua 用户数据 : Unable to have simultaneous array access and methods

javascript - -nan 在 C++ 中是什么意思?为什么 pow(-4, -2.1) 返回 -nan?

c++ - Ogre3d:遍历子节点错误

c++ - POSIX:如何暂停线程?

c++ - Lua 和 C++ 中的有限状态机

java - JNI : Callback from JVM to C++ fails to run

c++ - 如何在 Lua 代码中扩展 SWIG 的用户数据?