我有一个可以阅读Lua的类,因此我想制作一个类,以便您可以一次加载多个脚本并且不会发生冲突,也就是说,当另一个脚本被保存时,Lua变量的值将保存在第一个脚本中。被执行。
我希望程序将其输出-
print = 123
print = Hi 0
Result = 3
print = Hi 1
Result = 3
print = Hi 2
Result = 3
print = Hi 3
Result = 3
print = Hi 4
Result = 3
print = Hi 5
Result = 3
print = Hi 6
Result = 3
print = Hi 7
Result = 3
print = 123
print = Hi 0
Result = 3
print = Hi 1
Result = 3
print = Hi 2
Result = 3
print = Hi 3
Result = 3
print = Hi 8
Result = 3
print = Hi 9
Result = 3
print = Hi 10
Result = 3
print = Hi 11
Result = 3
但是她把它拿出来-
print = 123
print = Hi 0
Result = 3
print = Hi 1
Result = 3
print = Hi 2
Result = 3
print = Hi 3
Result = 3
print = Hi 4
Result = 3
print = Hi 5
Result = 3
print = Hi 6
Result = 3
print = Hi 7
Result = 3
print = 123
print = Hi 0
Result = 3
print = Hi 1
Result = 3
print = Hi 2
Result = 3
print = Hi 3
Result = 3
print = Hi 4
Result = 3
print = Hi 5
Result = 3
print = Hi 6
Result = 3
print = Hi 7
Result = 3
这是我的代码:
#pragma once
#pragma comment(lib, "lua53.lib")
extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
#include <iostream>
#include <LuaBridge/LuaBridge.h>
using namespace std;
using namespace luabridge;
class Lua_sup
{
private:
string m_name;
lua_State* L ;
bool init_state = false;
inline void PrintError(int run_status)
{
switch (run_status)
{
case LUA_ERRRUN:
{
printf( "LUA: Runtime Error: %s\n", lua_tostring(L, -1));
break;
}
case LUA_ERRSYNTAX:
{
printf("LUA: Syntax Error: %s\n", lua_tostring(L, -1));
break;
}
case LUA_ERRMEM:
{
printf("LUA: Memory Alloc Error: %s\n", lua_tostring(L, -1));
break;
}
case LUA_ERRERR:
{
printf("LUA: Error returning Error: %s\n", lua_tostring(L, -1));
break;
}
default:
{
printf("LUA: Unknown Error: %s\n", lua_tostring(L, -1));
break;
}
}
}
public:
Lua_sup(string name, lua_State* s);
~Lua_sup();
void init();
void test();
bool get_state() { return init_state; }
};
//.cpp
#include "Lua_sup.h"
void printMessage(const std::string& s) {
cout << "print = " << s << endl;
}
string get_string() {
return "Hi ";
}
Lua_sup::Lua_sup(string name, lua_State* s)
{
m_name = name;
L = lua_newthread(s);
}
Lua_sup::~Lua_sup()
{
lua_close(L);
}
void Lua_sup::init()
{
//L = luaL_newstate();
getGlobalNamespace(L).addFunction("printMessage", printMessage);
int load_status = luaL_loadfile(L, m_name.c_str());
if (load_status != 0) {
cout << "Error";
PrintError(load_status);
init_state = false;
}
lua_pcall(L, 0, 0, 0);
getGlobalNamespace(L).addFunction("get_string", get_string);
getGlobalNamespace(L).addFunction("printMessage", printMessage);
init_state = true;
}
void Lua_sup::test()
{
LuaRef hello_world_sum = getGlobal(L, "hello_world_sum");
LuaRef plot = getGlobal(L, "plot");
for (int i = 0; i < 3; i++)
{
int result = hello_world_sum(1, 2);
cout << "Result = " << result << endl;
}
int result = hello_world_sum(1, 2);
cout << "Result = " << result << endl;
getchar();
}
//my main
#include "Lua_sup.h"
using namespace luabridge;
int main() {
lua_State* L = luaL_newstate();
luaL_openlibs(L);
Lua_sup lua("script.lua", L);
lua.init();
lua.test();
lua.test();
Lua_sup lua1("123.lua", L);
lua1.init();
lua1.test();
lua.test();
}
我正在使用Luabridge
答案 0 :(得分:0)
您想要的是使用各自的环境加载每个文件。我可以满怀信心地告诉您如何从Lua做到这一点,但是由于您使用的是C(++),所以我只能依靠该手册says,该手册在加载Lua代码时会设置环境到“在注册表中的索引LUA_RIDX_GLOBALS处”(我假设您知道C注册表以及如何访问它)。
由于您很可能希望原始环境保持可用,因此您必须创建一个新的环境,并将其元表设置为__index原始环境。请记住,这仍然允许代码通过_G
变量显式设置全局变量,这可能是一件好事。
这是Lua中的等效代码,您必须将其移植到C:
local meta = {_index=_G}
-- Metatable for the new environment
local function load_sandboxed(file)
local new_env = setmetatable({}, meta}
-- Create a new environment with metatable. Missing keys
-- will be looked for in _G before returning nil
loadfile(file, "t", new_env)
-- Load the file with a custom environment.
-- Only allow text files.
end
答案 1 :(得分:0)
每个Lua_sup
实例都需要它自己的lua_State
实例。
int main()
{
lua_State* stateA = luaL_newstate();
luaL_openlibs(stateA);
Lua_sup lua("script.lua", stateA);
lua.init();
lua.test();
lua.test();
lua_State* stateB = luaL_newstate();
luaL_openlibs(stateB );
Lua_sup lua1("123.lua", stateB );
lua1.init();
lua1.test();
lua.test();
lua_close(stateA);
lua_close(stateB);
}
这会将每个脚本分开,并且它们不会交互。
请注意,完成状态后关闭状态是个好主意