使用句柄从.lua调用lua函数?

Kar*_*rok 1 c++ lua lua-api

我正在研究一个试图将lua与c ++集成的小项目.我的问题如下:

我有多个lua脚本,我们称之为s1.lua s2.lua和s3.lua.其中每个都具有以下功能:setVars()和executeResults().

现在,我可以通过LuaL_dofile调用lua文件,并在使用setVars()和/或executeResults()之后立即调用.这里的问题是,在我加载s2.lua之后,我再也无法调用s1.lua的函数了.这意味着我必须重做s1.lua上的LuaL_dofile以重新获得对该函数的访问权限,这样我就无法访问s2.lua中的函数.

有没有办法简单地加载所有lua文件,然后开始随意调用它们的函数?类似于s1-> executeResults()s5-> executeResults()s3-> setVars()等.

我目前已经有一个系统使用boost :: filesystem来检测文件夹中的所有lua文件,然后我将这些文件名保存在一个向量中,然后简单地迭代向量以连续加载每个lua文件.

在使用lua文件名填充向量时,我的插件加载函数现在看起来像这样:

void Lua_plugin::load_Plugins(){
 std::vector<std::string>::const_iterator it;
 for (it=Lua_PluginList.begin(); it!=Lua_PluginList.end(); it++){
  std::cout<<"File loading: " << *it << std::endl;
  std::string filename =  *it;
  std::string filepath = scriptdir+filename;
  if (luaL_loadfile(L, filepath.c_str()) || lua_pcall(L, 0, 0, 0)) {
   std::cout << "ScriptEngine: error loading script. Error returned was: " << lua_tostring(L, -1) << std::endl;
  }
 }
}
Run Code Online (Sandbox Code Playgroud)

为了使它更清楚一点,我在.lua中的所有内容都是这样的:

-- s1.lua

setVars()
--do stuff
end

executeResults()
--dostuff
end
Run Code Online (Sandbox Code Playgroud)

等,但我希望能够在连续加载两个之后调用s1.lua的setVars()和s2.lua的setVars().

Jud*_*den 6

这实际上是gwell使用C API提出的:

#include <stdio.h>

#include "lua.h"

static void
executescript(lua_State *L, const char *filename, const char *function)
{
    /* retrieve the environment from the resgistry */
    lua_getfield(L, LUA_REGISTRYINDEX, filename);

    /* get the desired function from the environment */
    lua_getfield(L, -1, function);

    return lua_call(L, 0, 0);
}

static void
loadscript(lua_State *L, const char *filename)
{
    /* load the lua script into memory */
    luaL_loadfile(L, filename);

    /* create a new function environment and store it in the registry */
    lua_createtable(L, 0, 1);
    lua_getglobal(L, "print");
    lua_setfield(L, -2, "print");
    lua_pushvalue(L, -1);
    lua_setfield(L, LUA_REGISTRYINDEX, filename);

    /* set the environment for the loaded script and execute it */
    lua_setfenv(L, -2);
    lua_call(L, 0, 0);

    /* run the script initialization function */
    executescript(L, filename, "init");
}

int
main(int argc, char *argv[])
{
    lua_State *L;
    int env1, env2;

    L = (lua_State *) luaL_newstate();
    luaL_openlibs(L);

    loadscript(L, "test1.lua");
    loadscript(L, "test2.lua");

    executescript(L, "test1.lua", "run");
    executescript(L, "test2.lua", "run");
    executescript(L, "test2.lua", "run");
    executescript(L, "test1.lua", "run");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

测试脚本:

-- test1.lua
function init() output = 'test1' end
function run() print(output) end

-- test2.lua
function init() output = 'test2' end
function run() print(output) end
Run Code Online (Sandbox Code Playgroud)

输出:

test1
test2
test2
test1
Run Code Online (Sandbox Code Playgroud)

为简洁起见,我省略了所有错误处理,但您要检查返回值luaL_loadfile并使用lua_pcall而不是lua_call.