【问题标题】:Create and access Lua object in Lua, that is stored in a C++ program在 Lua 中创建和访问 Lua 对象,该对象存储在 C++ 程序中
【发布时间】:2015-07-19 07:50:46
【问题描述】:

也许我不擅长谷歌搜索,也许我想多想,但如果我有这个 Lua 类:

--Foo:
Foo = {number = 0}
function Foo.setNumber(newNumber)
    number = newNumber
end

如果我尝试在另一个 .lua 文件中使用此类,则在文件结束后,该对象将被销毁。我看到的其他使用 Lua (like here) 的教程假设 C++ 程序已经知道该类,因此它被定义为普通的 C++ 类。然而,在我的例子中,Lua 的意义在于 C++ 程序只是一个处理绘图等的框架,所以不能有硬编码到程序中的 Lua 类。

所以,我的问题是,如何使用 Lua 定义和保留 Lua 对象,但除非我明确告诉它,否则该对象不会被销毁?我正在考虑在 C++ 中创建一个存储 Lua 对象的向量/映射的类,然后 Lua 脚本可以使用公开的函数请求对象。不幸的是,这听起来很慢,因为 Lua 要执行一个函数,它需要从 C++ 接收类的副本,调用类的函数,然后将其发送回 C++ 以覆盖之前的副本。

这里有一些代码是从EliasDaler's 修改的关于我如何运行 Lua 脚本的教程(这是非常好的 IMO):

#include <lua.hpp>
#include <LuaBridge.h>

#include <string>

//Example class to expose (I realise it's very similar to Foo):
class Bar
{
    private:
        std::string string;

    public:
        void setString(const std::string& newString) {string = newString;}
}

int main()
{
    //Expose the API:
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    luabridge::getGlobalNamespace(L)
    .beginClass<Bar>("Bar")
        .addConstructor<void(*)(void)>()
        .addFunction("setString", &Foo::setString)
    .endClass();

    //Run the script:
    luaL_dofile(L, "script.lua");
    luaL_openlibs(L);
    lua_pcall(L, 0, 0, 0);
    return 0;
}

【问题讨论】:

  • 我认为这取决于你如何从 C++ 调用 lua 脚本。
  • @stgatilov 你是什么意思?比如我用的是什么库?
  • 如果你从控制台运行“lua a.lua”和“lua b.lua”,那么它们肯定不会共享全局变量。我假设您从 C++ 代码调用 LUA 脚本。然后有必要确保两个脚本使用相同的 LUA 状态。这就是为什么我要求您提供有关如何运行 LUA 脚本的更多详细信息。
  • @stgatilov 我一直在通过使用 Luabridge 公开我的 API 来运行 Lua 脚本,然后也使用 luabridge 运行某个文件夹中的所有 .lua 文件(我将在我的问题中添加一些代码)

标签: c++ object lua


【解决方案1】:

在 Lua 中,所有的全局变量都存储在全局表 _G(称为environment)中。除非有人明确修改它,否则只有在 Lua state 被销毁时才会被销毁。

因此,您可以使用以下命令运行第二个脚本:

luaL_dofile(L, "another_script.lua");

它应该会看到第一个脚本留下的全局变量,因为该脚本使用与第一个相同的 Lua 状态。

【讨论】:

    【解决方案2】:

    Lua 通过垃圾回收管理自己的生命周期。如果它看不到正在使用的对象,它将销毁它。诀窍是将这些对象存储在一个 lua 表中,由 c++ 添加和删除它们,控制它们的生命周期。

    【讨论】:

    • 但是所有的全局变量都存储在一个特殊的表中,不是吗?我认为只有当 LUA 状态被破坏(这是 LUA 程序的终止)时,全局变量才会被破坏。
    • @stgatilov 所以你告诉我,只要我保持 Lua 状态,我就没事?如果是这样,我可能只是想多了,没有完全理解 Lua 的工作方式
    • 这取决于lua中对象的生命周期。如果对象是全局对象,则它会存在。如果对象是 lua 函数中的本地对象,那么当该函数返回 C++ 时,它将需要其他一些 lua 存在以避免被收集。
    猜你喜欢
    • 2021-08-14
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    • 2019-02-18
    • 2021-06-10
    • 2015-08-08
    • 2012-04-03
    相关资源
    最近更新 更多