Как я могу загрузить несколько скриптов без проблем с переменными - PullRequest
0 голосов
/ 27 июня 2019

У меня есть класс, с помощью которого я читаю 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

Ответы [ 2 ]

0 голосов
/ 04 июля 2019

Каждый экземпляр 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);
}

Это сохраняет каждый скрипт отдельно и он не взаимодействует.

Обратите внимание, что это хорошая идея, чтобы закрыть ваши состояния, когда вы закончите с ними

0 голосов
/ 27 июня 2019

То, что вы хотите, это загрузить каждый файл с его собственной средой. Я мог бы с уверенностью сказать вам, как это сделать с Lua, но, поскольку вы используете C (++), я могу рассчитывать только на руководство, которое говорит , что при загрузке кода Lua он будет устанавливать среда для "в индекс LUA_RIDX_GLOBALS в реестре" (я предполагаю, что вы знаете о реестре C и как получить к нему доступ).

Поскольку вы, скорее всего, хотите, чтобы исходная среда оставалась доступной, вам придется создать новую среду с метатабельным набором, равным __индексировать исходную. Имейте в виду, что это все еще позволит коду явно устанавливать глобальные переменные через переменную _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
...