Anonymous
Жаль что я не знаю так хорошо луашный апи
Anonymous
Возможно там можно достать какое-то обобщенное значение?
Igor
Не то слово, полгугла перерыл, но везде только на материал про вызов сишных функций натыкаюсь
Anonymous
Ну это если нет отдельного типа для функции
Anonymous
Что то типа луашного воид*
Igor
вообще сейчас попробую одну штуку
Igor
сдаётся мне, что сработает
Igor
сомневаюсь конечно, что мне в лицо краш не прилетит, но попробовать стоит, раз уж идея пришла
Anonymous
Хорошо, напиши пожалуйста, если получится
Igor
кк
Igor
ех, не вышло
Igor
Последним вариантом у меня осталось только передавать в сишную функцию не саму луёвую функцию, а её имя строкой и хранить её в глобальной таблице, получать через lua_getglobal, но этого мне меньше всего хотелось бы
Igor
Но если не предложат более изящного решения, то именно так и придётся сделать
Denis
а передать таблицу с функцией? Вида:
{
do = function() print("done!") end
}
тоже не очень изящно)
Igor
Вариант сам по себе не очень изящный, да, и тем более если внутри машины не будет ссылок на эту таблицу, то GC её подчистит, а хранить таблицу в переменной не очень затея, если и писать что-то в переменную, то только функцию без обвесов в виде таблицы, ибо тут они уже ненужными получаются
Snusmumriken
И снова у меня вопрос по C API луёвому.
Как мне правильно организовать вызов функции переданной в другую? То есть, предположим, что есть функция register у которой вторым аргументом передаётся другая функция (луёвая, не сишная, тут lua_tocfunction не прокатит) и эта переданная функция будет через какое-то время вызвана, но уже из другого места, то есть не из того же контекста. Как мне получить что-то типа ссылки на эту функцию, чтобы потом отправить её в стек и как обычно вызвать через lua_pcall/lua_call? Цель, если это важно, Lua 5.3.5
if (lua_isfunction(L, -1)) {
lua_pushnumber(L, 100);
lua_pushnumber(L, 500);
// вызываем с двумя аргументами и одним ретурном
lua_call(L, 2, 1);
std::cout << lua_tonumber(L, -1) << std::endl;
}
При передаче функции типа
function(a, b) return a + b end оно выведет 600.
Igor
Вся загвоздка в том, что в стеке не будет на -1 позиции функции
Igor
Надо как-то сделать так, чтобы она там оказалась
Igor
В функции register она не взыывется
Snusmumriken
Перемещаешь её куда тебе нужно.
lua_remove/lua_insert
Igor
Она должна будет вызваться позже из другого места
Snusmumriken
Сохрани её в луа-таблицу.
Snusmumriken
У меня вот такое мега-решение. Я сохраняю функцию в одну из библиотечных табличек ))
Колбеки, все дела. Потом напихаю тонну аргументов и вызову по ключу-значению.
Snusmumriken
Потом дёргаю это примерно так. Первая фигня — создаёт запись в табличке, вторая — вызывает когда надо.
Snusmumriken
(ммм, костыли, теперь банановые)
Igor
Хм, спасибо за разъяснение, но мне чего-то такое большое городить не сильно хочется, так что просто воспользуюсь глобальной таблицей, так уж и быть, к тому же придумал один способ интересный. Сначала на глобальной таблице сделаю, а потом если будет желание, то сделаю примерно как у тебя.
Anonymous
Я даже понял
Anonymous
Хехе
Snusmumriken
Anonymous
А можно у таблицы оператор вызова задать?
Snusmumriken
setmetatable и __call?
Igor
Метатаблицы
Igor
Ага
Anonymous
Дада я про ето
Anonymous
Тогда можно вообще таблицу вместо функции использовать
Snusmumriken
Читани как работает
https://habr.com/ru/post/346892/
Snusmumriken
Можно
Anonymous
Но если я правильно понимаю все это просто проеб С апи
Anonymous
Вся ета история
Snusmumriken
Да нет, это нормальная ситуация. Надо куда-то сохранить луёвую функцию чтобы потом её вызвать.
Snusmumriken
Можно сохранить ссылку на функцию в сишной структуре (или в мапе), но это не интересно.
Anonymous
Сишную уже функцию т.е.?
Snusmumriken
Нет, луёвую.
Anonymous
Аа
Igor
А как вообще lua-функция в машине представляется? В код сейчас просто залезть не могу и посмотреть
Snusmumriken
Сишную уже функцию т.е.?
Потом вытряхнешь её из луёвого регистра через
lua_rawgeti(L, LUA_REGISTRYINDEX, pointer_to_lua_func);
И вот она в стеке, можно вызывать.
Anonymous
Понятно, спасибо
Anonymous
Ну структура может быть и из двух полей так то
Igor
Надо будет как-нибудь выкроить времени кучку и залезть поглубже в lua машину, посмотреть, как там да что
Snusmumriken
А. Самая полезная функция при работе с C-api:
void luax_printstack(lua_State * L) {
std::cout << "Stack start: " << std::endl;
for (int i = 1; i <= lua_gettop(L); i++) {
std::cout << " " << i << " - " << luaL_typename(L, i);
int t = lua_type(L, i);
switch (t) {
case LUA_TSTRING:
std::cout << " " << std::string(lua_tostring(L, i)).substr(0, 30);
case LUA_TBOOLEAN:
std::cout << " " << (lua_toboolean(L, i) ? "true" : "false");
case LUA_TNUMBER:
std::cout << " " << lua_tonumber(L, i);
}
std::cout << std::endl;
}
}
Просто вывод содержимого стека. Если это числа/строки — вывод и их.
Для плюсов, но легко адаптируется.
Igor
Ага. У меня уже есть подобная
Snusmumriken
Намана
Anonymous
Есть же сол
Anonymous
Если плюсы
Snusmumriken
Сол — это отдельное костылестроение ))
Лично я не люблю эту фигню тем, что надо изучать её полностью, чтобы более-менее понимать что происходит. Но кому-то нравится. Ещё есть tolua, с тем же результатом.
Anonymous
Понятно
Anonymous
У меня у сестры кота звали сол
Anonymous
Сул точнее
Anatoliy
Всем привет, ребята подскажите, кто для луа dll'ки компилил, как сделать dll совместимую и с луа 5.1 и с луа 5.3, там как то луёвый хедер compat.h подключается из c-api и в определения препроцессора чтото надо прописать
akamit
привет.. а как то можно в lua try, except сделать?
мне надо attempt to index a nil value отловить
Mikhail
akamit
пробовал так if var and var[1][2][3] ~= nil
Mikhail
не надо писать ~= nil
Mikhail
почитай про нее
Mikhail
она по сути как try catch
akamit
но только этот try надо в функцию оборачить да?
akamit
а что то простое вроде newvar = a[1][2][3] or 0
akamit
нет такого?)
Alexey
Я вижу 2 варианта.
1 использовать только C функции определенные а обеях версиях api. Нужно явно следить за макросами и не уверен что это вариант.
2. Написать свою обертку и динамически выбирать нужную функцию и опять таки нужно следить за макросами. Вроде видел такую библиотеку для lua 5.2
Alexey
Mikhail
но я добавляю проверки типа
if a[1] and a[1][2] and a[1],,,,
akamit
ну там вообще такой переменной нет.
Mikhail
любит народ усложнять. ну да ладно. удач!!!
akamit
или индексов
Alexey
ну там вообще такой переменной нет.
можно функцию сделать pget(a,1,2,3)
Можно метатаблицу к nil прикрутить если очень хочется сохранить синтаксис. Но тогда отладка может стать намного сложнее
Snusmumriken
пробовал так if var and var[1][2][3] ~= nil
Функция спуска по ключам выглядит примерно так
function getValue(t, ...)
for i = 1, select('#', ...) do
local v = select(i, ...)
if type(t) ~= 'table' then
return nil, (i - 1) .. " key doesn't find a table"
end
t = t[v]
end
return t
end