2015-07-19 91 views
0

也许我坏在谷歌搜索,也许我尝试过想事情,但如果我有这样的Lua类:创建和Lua中访问的Lua对象,存储在C++程序

--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; 
} 
+0

我认为这取决于你如何从C++调用lua脚本。 – stgatilov

+0

@stgatilov你是什么意思?像我正在使用的库? – bboy3577

+0

如果你从控制台运行“lua a.lua”和“lua b.lua”,那么它们肯定不会共享全局变量。我假设你从C++代码调用LUA脚本。然后有必要确保这两个脚本都使用相同的LUA状态。这就是为什么我要求你提供更多关于你如何运行LUA脚本的细节。 – stgatilov

回答

2

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

所以,你可以运行第二个脚本:

luaL_dofile(L, "another_script.lua"); 

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

1

Lua中通过垃圾收集管理它自己的寿命。如果它看不到一个对象被使用,它会破坏它。诀窍是将这些对象存储在lua表中,C++将它们添加和删除,以控制它们的生命周期。

+0

但是所有全局变量存储在一个特殊的表格中,不是吗?我认为全局变量只有在LUA状态被销毁时才被销毁(这是LUA程序的终止)。 – stgatilov

+0

@stgatilov所以你告诉我,只要我保持Lua州,我很好?如果是这样的话,我可能只是过分揣测事物,并不完全理解Lua的工作方式 – bboy3577

+0

这取决于lua中物体的寿命。如果对象是全局的,它就会存活下来。如果该对象是lua函数中的本地对象,那么当该函数返回到C++时,它将需要一些其他的lua存在来避免被收集。 – mksteve