#lua #luac
#lua #luac
Вопрос:
Моя проблема в том, что lua_pcall очищает стек, потому что я хочу повторно использовать стек перед повторным вызовом с одним изменением еще раз.
Есть ли способ либо скопировать весь стек и вставить его снова, либо даже вызвать функцию lua без очистки стека?
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;
}
Комментарии:
1. Привет! Не могли бы вы более четко объяснить? Попробуйте отредактировать свой пост и добавить форматирование, чтобы выразить свою точку зрения (вы не использовали разрывы строк или разные предложения, что затрудняет понимание вашей точки зрения). Увидимся на SO 😉
2. Возможно, вам нужно создать функцию C, которая может вызываться из Lua — они получают текущий стек плюс аргументы функции в нем; или сделайте так, чтобы ваш API получал закрытие. Они могут сохранять свое собственное состояние, и поэтому не имеет значения, очищен ли стек — до тех пор, пока вы вызываете то же самое состояние Lua ofc.
3. @dualed я обновил пример кода, у меня проблема в том, что стек очищен от lua_pcall , я хочу вызвать несколько функций из функции lua, и мне нужен способ либо сохранить и скопировать стек перед вызовом, либо вызвать функцию lua без сброса стека с помощью lua_pcall.
4. Возможно, я только что понял, о чем вы спрашиваете, и исходил из совершенно другого предположения — если вы думаете, что ваш код на C становится громоздким или медленным из-за многократного нажатия на стек, тогда вы думаете неправильно; Также
pcall
на самом деле не очищает аргументы вашей функции из стека, думайте об этом как о функции, потребляющей их — это просто то, как работает Lua C API. Не связывайтесь со стеком…5. @Marlonie2010 Вы должны опубликовать свое решение в качестве ответа, вместо того, чтобы добавлять его к своему вопросу — нет ничего изначально неправильного в ответе на ваш собственный вопрос
Ответ №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);
Я решил проблему, используя таблицу в реестре и поместив полный стек в таблицу с цифровыми ключами. После вызова второй части я могу вернуться к стеку, когда была вызвана первая часть, но несколько раз.