我刚接触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)