2014-03-06 140 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

太棒了!很好,很简单,谢谢:) –