2015-07-19 37 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