2014-03-06 72 views
1

我有一個C++類,我想通過一個全局變量來提供訪問的LUA腳本,但是當我嘗試使用它,我得到以下錯誤:luabind:不能訪問全局變量

terminate called after throwing an instance of 'luabind::error' 
    what(): lua runtime error 
baz.lua:3: attempt to index global 'foo' (a nil value)Aborted (core dumped) 

我的Lua腳本(baz.lua)看起來是這樣的:

-- baz.lua 
frames = 0 
bar = foo:createBar() 

function baz() 
    frames = frames + 1 

    bar:setText("frame: " .. frames) 
end 

而且我做了一個簡單和短(以及我可以)main.cpp中,再現這個問題:

#include <memory> 
#include <iostream> 

extern "C" { 
    #include "lua.h" 
    #include "lualib.h" 
    #include "lauxlib.h" 
} 

#include <boost/ref.hpp> 
#include <luabind/luabind.hpp> 

class bar 
{ 
public: 
    static void init(lua_State *L) 
    { 
    using luabind::module; 
    using luabind::class_; 

    module(L) 
    [ 
     class_<bar>("bar") 
     .def("setText", &bar::setText) 
    ]; 
    } 

    void setText(const std::string &text) 
    { 
    std::cout << text << std::endl; 
    } 
}; 

class foo 
{ 
public: 
    foo() : 
    L(luaL_newstate()) 
    { 
    int ret = luaL_dofile(L, "baz.lua"); 
    if (ret != 0) { 
     std::cout << lua_tostring(L, -1); 
    } 

    luabind::open(L); 

    using luabind::module; 
    using luabind::class_; 

    module(L) 
    [ 
     class_<foo>("bar") 
     .def("createBar", &foo::createBar) 
    ]; 

    bar::init(L); 
    luabind::globals(L)["foo"] = boost::ref(*this); 
    } 

    boost::reference_wrapper<bar> createBar() 
    { 
    auto b = std::make_shared<bar>(); 
    bars_.push_back(b); 

    return boost::ref(*b.get()); 
    } 

    void baz() 
    { 
    luabind::call_function<void>(L, "baz"); 
    } 

private: 
    lua_State *L; 
    std::vector<std::shared_ptr<bar>> bars_; 
}; 

int main() 
{ 
    foo f; 

    while (true) { 
    f.baz(); 
    } 
} 

這編譯:

g++ -std=c++11 -llua -lluabind main.cpp 

我發現,如果我把bar = foo:createBar()baz()函數,那麼它不會出錯,所以我想我不會在全局命名空間正確初始化的全局?我是否錯過了在我能夠做到這一點之前需要調用的luabind函數?或者這是不可能的...

謝謝!

回答

2

在註冊任何全局變量之前,您正在運行baz.lua。在註冊綁定之後放入dofile命令。

順序如下:

  • 您調用FOO在C++構造函數,它
  • 創建一個Lua狀態
  • 運行lua.baz
  • 登記您的綁定
  • 然後在C++調用f.baz。
+0

太棒了!很好,很簡單,謝謝:) –