Есть ли функция API lua-c, которая не удаляет весь стек?

Моя проблема в том, что lua_pcall очищает стек, потому что я хочу повторно использовать стек перед вызовом снова с одним изменением снова.
Есть ли способ либо скопировать весь стек и снова вставить его, либо даже способ вызвать функция lua без очистки стека?

Луа:

function test(a)
    print(a)
end

event.add("test", test)
event.add("test", test)

event.call("test", 42)

C++:

int Func_Event_call(Lua_State* L){

    //Stack: String:Eventname, Arguments...

    std::string name = luaL_checkstring(L, 1);

    ... Get array functions from name

    for(...){

        //load function into stack
        lua_rawgeti(L, LUA_REGISTRYINDEX, functions[c]);
        lua_replace(L, 1);

        //Wanted Stack: Lua_Function, Arguments... <- works for the first function

        //call function
        lua_pcall(L, nummberArgs, 0, 0);

        //stack is now empty because of lua_pcall <- problem
    }

    return 0;
}

person Marlonie2010    schedule 23.04.2019    source источник
comment
Привет ! Не могли бы вы быть более четкими в своем объяснении? Попробуйте отредактировать свой пост и добавить немного форматирования, чтобы подчеркнуть свою точку зрения (вы не использовали разрывы строк или разные предложения, что затрудняет понимание вашей точки зрения). Увидимся на СО ;)   -  person matthiasbe    schedule 23.04.2019
comment
Возможно, вам нужно создать функцию C, которую можно вызывать из Lua — они получают текущий стек, а также аргументы функции; или сделайте так, чтобы ваш API получил закрытие. Они могут нести свое собственное состояние, поэтому не имеет значения, очищается ли стек - до тех пор, пока вы вызываете одно и то же состояние Lua ofc.   -  person dualed    schedule 23.04.2019
comment
@dualed я обновил пример кода, у меня проблема в том, что стек очищается от lua_pcall, я хочу вызвать несколько функций из функции lua и мне нужен способ либо сохранить и скопировать стек перед вызовом, либо вызвать функцию lua без сброс стека с помощью lua_pcall.   -  person Marlonie2010    schedule 23.04.2019
comment
Возможно, я только что понял, о чем вы спрашиваете, и придерживался совершенно другого предположения. Если вы думаете, что ваш код на С++ становится громоздким или медленным из-за многократного помещения вещей в стек, то вы думаете неправильно; Также pcall на самом деле не очищает аргументы вашей функции из стека, думайте об этом как о функции, потребляющей их - это просто то, как работает Lua C API. Не путайте со стеком...   -  person dualed    schedule 24.04.2019
comment
@ Marlonie2010 Marlonie2010 Вы должны опубликовать свое решение в качестве ответа, а не добавлять его к своему вопросу - в ответе на собственный вопрос нет ничего плохого по своей сути.   -  person dualed    schedule 25.04.2019


Ответы (1)


    //store stack in Registry
    lua_createtable(L, nummberArgs, nummberArgs);
    lua_insert(L, 1);

    //fill table
    for (int c = 0; c < nummberArgs; c++) {

        lua_pushinteger(L, c);
        lua_insert(L, -2);
        lua_settable(L, 1);

    }

    //store it in Registry and clean up
    int reg_key = luaL_ref(L, LUA_REGISTRYINDEX);
    lua_remove(L, 1);

    ...

    //restore stack from above
    lua_rawgeti(L, LUA_REGISTRYINDEX, reg_key);

    //iterate over the table to get all elements, the key is getting removed by lua_next
    lua_pushnil(L);
    while (lua_next(L, 1) != 0) {
        /* uses 'key' (at index -2) and 'value' (at index -1) */
        /* move 'value'; keeps 'key' for next iteration */
        lua_insert(L, -2);
    }

    //remove table from stack
    lua_remove(L, 1);

Я решил проблему с помощью таблицы в реестре и поместил полный стек в таблицу с числовыми ключами. После вызова второй части я могу вернуться к стеку, когда была вызвана первая часть, но несколько раз.

person Marlonie2010    schedule 26.04.2019