尝试在单独的lua状态下运行脚本时的Lua问题

时间:2014-10-25 22:19:40

标签: c++ lua lua-api

我刚接触Lua,并且在我的旅途中成功实现了这一目标。我将luaL_loadfile的结果存储到全局中,以便可以重复调用它。我当前的问题是,当我尝试在当前脚本状态以外的状态下在脚本内运行脚本时,我会遇到段错误。

struct State
{
    // deleted and defaulted ctors removed for brevity
    State(std::string name, uint32_t id) : 
        id(id), state(luaL_newstate()), name(std::move(name))
    {
        assert(this->state != nullptr && "state is nullptr");
        assert(this->name != "" && "Name is empty");

        luaL_openlibs(state);
        lua_settop(state, 0);
    }

    ~State()
    {
        lua_close(state);
    }

    uint32_t id;
    lua_State* state;
    std::string name;
};

struct Script
{
    // deleted and defaulted ctors removed for brevity
    Script(std::string name, uint32_t id, uint32_t stateId) :
        id(id), stateId(stateId), name(name) { }

    uint32_t id;
    uint32_t stateId;
    std::string name;
};

以下是脚本的加载方式:

bool ScriptEngine::LoadScript(State& state, std::string filename)
{
    auto success(luaL_loadfile(state.state, filename.c_str()) == 0);
    lua_setglobal(state.state, filename.c_str());

    scripts.emplace_back(filename, nextScriptId, state.id);
    ++nextScriptId;

    return success;
}

我的执行功能:

 int ScriptEngine::RunScript(Script& script)
 {
    auto state(GetState(script.stateId));
    assert(state != nullptr && "Script state is invalid");

    lua_getglobal(state->state, script.name.c_str());
    // Segfaults in the above line in index2adr called by lua_getfield 
    // if the state is not the same as the current state

    auto top(lua_gettop(state->state));
    if(lua_pcall(state->state, 0, LUA_MULTRET, 0))
    {
        std::cout << "unable to run script " << script.name << " " << 
            lua_tostring(state->state, -1) << std::endl;
        assert(0);
    }

    return top - lua_gettop(state->state);
}

我的绑定调用ScriptEngine :: RunScript(Script&amp;)

int RunScript(lua_State* state)
{
    auto script((Script*)lua_touserdata(state, -1));

    lua_pushliteral(state, "ScriptEngine"); 
    lua_gettable(state, LUA_REGISTRYINDEX);

    auto engine((ScriptEngine*)lua_touserdata(state, -1));

    return engine->RunScript(*script);
}

我的测试脚本:

local script = ScriptEngine.GetScript("config.txt")
print(script)

local rets = ScriptEngine.RunScript(script)
-- crash happens in the above line if the target script has a 
-- separate state than this script itself

print(rets)

0 个答案:

没有答案