Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从.lua';调用lua函数;他在用把手吗? 我正在研究一个小项目,试图把Lua与C++结合起来。 然而,我的问题如下:_C++_Lua_Lua Api - Fatal编程技术网

从.lua';调用lua函数;他在用把手吗? 我正在研究一个小项目,试图把Lua与C++结合起来。 然而,我的问题如下:

从.lua';调用lua函数;他在用把手吗? 我正在研究一个小项目,试图把Lua与C++结合起来。 然而,我的问题如下:,c++,lua,lua-api,C++,Lua,Lua Api,我有多个lua脚本,让我们把它们称为s1.luas2.lua和s3.lua。其中每个函数都有以下函数:setVars()和executesults() 现在我可以通过LuaL_dofile调用lua文件,并在使用setVars()和/或executeResults()后立即调用。然而,这里的问题是,在加载s2.lua之后,我无法再调用s1.lua的函数。这意味着我必须在s1.lua上重做LuaL_dofile以重新获得对函数的访问权,这样我就失去了对s2.lua中函数的访问权 有没有一种方法可以

我有多个lua脚本,让我们把它们称为s1.luas2.lua和s3.lua。其中每个函数都有以下函数:setVars()和executesults()

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

有没有一种方法可以简单地将所有lua文件装入一行,然后开始随意调用它们的函数?类似s1->executesults()s5->executesults()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;
  }
 }
}
等等,但我希望能够在一行中加载s1.lua的setVars()和s2.lua的setVars()之后调用它们。

可以使用
setfenv()
函数为加载的每个文件创建or环境

此示例显示,所有三个文件都可能加载有冲突的函数,并且可以按任意顺序调用这些函数。类似的代码可以用C++编写。本例仅将打印功能导出到每个环境,在您的场景中可能需要更多

function newEnv()
  -- creates a simple environment
  return {["print"]=print}
end

local e={} -- environment table
local c    -- chunk variable

-- first instance
c = loadstring([[function f() print("1") end]])
e[#e+1] = newEnv()
setfenv(c, e[#e]) -- set the loaded chunk's environment
pcall(c) -- process the chunk (places the function into the enviroment)

-- second instance
c = loadstring([[function f() print("2") end]])
e[#e+1] = newEnv()
setfenv(c, e[#e])
pcall(c)

-- third instance
c = loadstring([[function f() print("3") end]])
e[#e+1] = newEnv()
setfenv(c, e[#e])
pcall(c)

pcall(e[3].f) --> 3
pcall(e[2].f) --> 2
pcall(e[1].f) --> 1
pcall(e[1].f) --> 1
pcall(e[2].f) --> 2
pcall(e[3].f) --> 3

可以使用
setfenv()
函数为加载的每个文件创建一个or环境

此示例显示,所有三个文件都可能加载有冲突的函数,并且可以按任意顺序调用这些函数。类似的代码可以用C++编写。本例仅将打印功能导出到每个环境,在您的场景中可能需要更多

function newEnv()
  -- creates a simple environment
  return {["print"]=print}
end

local e={} -- environment table
local c    -- chunk variable

-- first instance
c = loadstring([[function f() print("1") end]])
e[#e+1] = newEnv()
setfenv(c, e[#e]) -- set the loaded chunk's environment
pcall(c) -- process the chunk (places the function into the enviroment)

-- second instance
c = loadstring([[function f() print("2") end]])
e[#e+1] = newEnv()
setfenv(c, e[#e])
pcall(c)

-- third instance
c = loadstring([[function f() print("3") end]])
e[#e+1] = newEnv()
setfenv(c, e[#e])
pcall(c)

pcall(e[3].f) --> 3
pcall(e[2].f) --> 2
pcall(e[1].f) --> 1
pcall(e[1].f) --> 1
pcall(e[2].f) --> 2
pcall(e[3].f) --> 3

您可以为每个文件创建一个新的状态
lua\u newstate()
。这比我以前的回答要容易。但是,它可能会有性能损失。

您可以为每个文件创建一个新状态
lua\u newstate()
。这比我以前的回答要容易。但是,它可能会有性能损失。

这实际上是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;
}
输出:

test1
test2
test2
test1
为了简洁起见,我省略了所有的错误处理,但是您需要检查
luaL\u loadfile
的返回值,并使用
lua\u pcall
而不是
lua\u call

这就是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;
}
输出:

test1
test2
test2
test1

为了简洁起见,我省略了所有错误处理,但是您首先要检查
luaL\u loadfile
的返回值,并使用
lua\u pcall
而不是
lua\u call

,谢谢!我在Lua的C++部分中查看了一下,我无法找到哪个函数将取代C++中的Lua的SETFEN()。这主要是因为我希望在我的C++代码中保留ADDON/PULLIN控件(除了与Lua相比,有点精通C++)。我假设可以将环境创建合并到Load_Plugins()函数中,对吗?环境列表是否可以被C++代码的其他部分使用?提前感谢更正在lua-users.org列表中发现的错误,这可能表明此函数已被弃用,但我仍将尝试:)弃用将取决于您使用的lua版本<代码>setfenv()将在5.2中被弃用。看到一些尝试稍后,我不能为我的生活找出如何上述LUA代码将转化为C++:(我假设我没有正确使用LuaAuStEnFeV和LuaGuffEnv,因为应用程序只是崩溃。首先,谢谢!我在Lua的C++部分中查看了一下,我无法找到哪个函数将在C++环境中替换Lua的SETFEN()。这主要是因为我想在我的C++代码中保留ADDON/PULIN控件。(除了与Lua相比,C++有一点精通),假设我可以在我的Load插件中加入环境创建,我会是正确的吗?函数?环境列表可由C++代码的其他部分使用?感谢在高级教程中发现的LUAUSER。ORG列表,它会建议这个函数被禁止,但是我还是会尝试它:无论如何,贬低将取决于你正在使用的Lua版本。<代码> SETFEN()将在5.2中被弃用。稍后再看一些尝试,我无法为我的生活找出上面的Lua代码是如何转化为C++的:(.我假设我没有正确使用lua_setfenv和lua_getfenv,因为应用程序会崩溃。如果只为每个lua文件创建一次新状态不会造成太大的性能损失,那么这应该不会是一个问题。对状态的二次和后续访问不应该经常发生。我想我会尝试newstate瘦gy,因为我仍然无法让lua_setfenv在不破坏应用程序的情况下工作:(再次感谢:)如果为每个lua文件只创建一次新状态不会造成太大的性能损失,那么这应该不会是一个问题。对状态的二次访问和后续访问不应该经常发生。我想我会尝试newstate,因为我仍然无法让lua_setfenv正常工作,而不会使应用程序崩溃:(再次感谢:)