Tverd
давай на гит, раз такие сложности с колбеками из C++
Alexey
Какие проблемы. Просто надо делать обертку и передавать как callback пару объект/метод
Alexey
Ну и не забывать про обработку Lua error/C++ exception
Snusmumriken
Основная сложность в том, что я не умею в с/с++ по-человечески : )
Сложности - конкретно с макросами стима, которые генерируют колбеки из связок объект-метод, через перегруженный кучей фигнёй макрос, и невозможность дёрганья этого счастья из ffi, ибо нет ООП и нет возможности дёргать макросы.
Плюс у меня лично развлекалово под названием "Подцепи либы/инклюды в visual studio, потому что mingw не работает ((", и "Ух ты, так вот как связывать .h-файлы с "основной" частью проги, теперь я понимаю зачем людям нужна IDE вместо редактора!" и много-много всякой смешной лабуды, типа "Почему на моём основном компе запускается, а на соседнем - нет? А, так там msvcrt по умолчанию дебажная, и она отсутствует на соседнем компе ибо там нет VS, и рантайм поехал! Я, правда, пока не знаю что это такое!"
Snusmumriken
Очень много инфы в мою бедную голову за короткие сроки : )
Ну, в общем, примерно глянуть колбечное общение между луа и плюсами можно тут:
https://bitbucket.org/MainTomato/steampower/src/83cb7d112c0a26ea74013d91cb31fad00a7f668a/SteamPower/?at=develop
Snusmumriken
Ну ты понел, нельзя сначала подрубить либу, а потом загнать туда кучу кода в компилятор сишки ))
Snusmumriken
Ох, я уже не один год калякаю ffi-биндинги, что как бы сишка.
Тут не "лучше использовать" - а невозможно использовать, в данном конкретном случае.
Alexey
C++ и FFI плохая идея со всех сторон :)
Snusmumriken
FFI не тянет C++, и этого достаточно. Хотя если через ffi подрубить jit-компилятор плюсов (о да) - теоретически можно.
Alexey
FFI желательно использовать c C API
Snusmumriken
Ох, да там не нужен C API, он и так прекрасен, автоматически апишится.
Если только не подрубать вот так: https://github.com/Playermet/luajit-tcc/blob/master/examples/base.lua
Alexey
В С++ есть подмножество С. Которое не полностью соответвует настоящему С
Alexey
extern "C" не делает функцию C-функцией
Alexey
оно просто отключает name mangling
Snusmumriken
Ну я примерно так и думал.
Но к чему это?
Типа, что луа с с++ вообще лучше не стыковать? Делать пять оболочек одна в другой, типа c++ -> c -> lua?
Alexey
и name mangling не является чем то стандартным и разные компиляторы использую свой механизм
в том чесле и патентованные. Т.е. угадать имя метода/функции С++ задача достаточно интересная
Alexey
Alexey
легкое движение и у тебя утечка. LuaCOM имеет такую
Alexey
в общем случае Lua не должна генерировать ошибки в С++ функциях.
A C++ не должен кидать исключения в Lua функциях.
Если конечно ты не используешь Lua собранную как C++ библиотеку.
Но тогда у тебы возникнут те же проблемы со сторонними Lua библиотеками
Snusmumriken
Моя жизнь состоит из интересных вещей, когда делаешь много-много-много действий, которые ничего как бы не значат, но через пол часа-час-пять-сутки оно внезапно начинает работать, по неизвестной причине, и где-то через пол года выясняется, почему именно.
На тему обработки исключений - пока не наблюдал ничего особенно страшного. Смотрел на сурцы love2d, оно написано на с++, и там есть много вспомогательных функций, и если и есть утечки - о них мало что сказанно.
Snusmumriken
Спасибо за предупреждения, кажется моя жизнь скоро станет ещё интереснее чем обычно.
Snusmumriken
Love2d - оболочка над SDL2, написанная на c++, выглядит примерно так:
https://bitbucket.org/rude/love/src/13eceb0e7ada48883c636b302847469fa72045cb?at=minor
Я делаю вообще кошмар, пишу с++-библиотеку которая реквайрится в луа.
Alexey
все очень просто
pcall не перехватит C++ исклучение
А такой с++ код
std::string s = "HELLO";
lua_error(L)
Не удалит s корректно.
Alexey
опять таки если Lua не собрана как C++
И желательно темже компилятором с теми же параметрами
Snusmumriken
Ммм.
void luax_pushstring(lua_State *L, const std::string &str)
{
lua_pushlstring(L, str.data(), str.size());
}
std::string s = "HELLO";
luax_pushstring(L, s);
delete s;
lua_error(L);
Тут точно где-то косяки с указателями, но суть ты понял мб.
Alexey
Это вообще не должно работать :)
убери delete s
Snusmumriken
Почему не должно? : )
Alexey
потому что delete s не скомпилируется :)
Snusmumriken
Пофигу, я только что это придумал, найди аналогию чтобы скомпилилось.
На текущий момент "два дня пишем на плюсах" - я не умею писать на них сразу в чат.
Alexey
И если lua_pushlstring сгенерирует ошибку то s ну удалится
Snusmumriken
Из-за чего оно сгенерирует?
Что заставит её сгенерировать ошибку?
Есть стак. В него можно пихать строки.
Можно - значит ошибок не генерирует. Разве что пихнуть туда что-то не строковое, но тут явно строковое, разве нет?
Alexey
Стек не безконечен да и физическая память тоже
Alexey
https://www.lua.org/manual/5.3/manual.html#lua_pushstring
Snusmumriken
Ты циклом собрался загонять данные в стек?
Я это уже прочитал.
Alexey
определена как [0,+1,m]
Snusmumriken
"Минимальный размер стека - 20 значений". Кто говорит что я не прочитал эти данные и не увеличу стек если что, и не сделаю проверку на его размер?
Alexey
Ну и пример из реальной жизни https://github.com/brimworks/lua-http-parser
Snusmumriken
Проблемы у C API - ровно те же самые.
При чём тут именно плюсы?
Alexey
там все пихается в стек.
Snusmumriken
А createtable и пихать в таблицу - не?
Она занимает одно значение в стеке. Ну, три, при внесении ключа-значения.
Alexey
так еще есть размер памяти. Или его ты тоже собираешся увеличивать :)
Alexey
Я это к тому что надо внимательно смотреть на код
Snusmumriken
Слушай, ты такой молодец, когда пишут "минимальные требования к приложениям" - указывают память : )
Alexey
std:string s1 = "hello";
luaL_check...
Snusmumriken
Карочи, не доводи до абсурда, ладно?
А то и я так могу сказать: "В луа нужно быть очень внимательным! 32-битные версии луа не тянут более 4гб, а luajit до 2.1.3 beta 3 - вообще только 1-2 гб!
Не делайте таблицы циклами:
for i = 1, 100000050000000 do t[i] = {1005000000} end, а то упадёт!!!!".
Alexey
при этом
char s[]="hello";
lua_check...
Работает
Snusmumriken
"Нельзя возвращать функциями более 1600 значений! А то упадёт!!! Нужно быть очень внимательным!!!! Не делайте return unpack(table)!!"
Alexey
Где то была статья про ABI С/С++.
Alexey
на моих тестах Lua 5.1/JIT ~9k Lua5.2/5.3 ~120k
Snusmumriken
Возвращаемых значений?
Snusmumriken
Там просто размер стека регулируется. Можно перекомпилить с нужным тебе размером.
Извращенец. С одной стороны, знать лимиты - хорошо, с другой - не так же маниакально, ёпть.
Alexey
https://travis-ci.org/moteus/lua-http-parser/jobs/290065710#L564
Alexey
Это число нужно увеличть на 3. т,к, каждый эвент это 3 объекта на стеке
Alexey
не 120 а 70 :)
Snusmumriken
Ох, карочи, давай серьёзнее, ладно?
Я пока не увидел ни одного нормального довода "с круче чем с++ при привязке к луа-апишке".
Если сишкой маллокать данные а потом передавать в луа-функции, очевидно их тоже надо освобождать. Оно "работает" когда ты пихаешь в функцию строчку как char array вместо std::string - только потому, что char array размечается на сишном(плюсовом) стеке и самоудаляется, а std::string - сразу в памяти размечается, потому и утечка. Ну, насколько я это понял, я не знаю как оно на самом деле работает. Всё что размечается не на стеке - ясное дело, нужно удалять, если уже не нужно.
Твои предъявы абсолютно идентичны и туда и туда.
А то что некоторые умники пихают ояебу сколько фигни в луа-стек - это их проблемы, не мои.
Alexey
C++ нормально все сам удаляет. И удалить что-то на стеке возможно но
достаточно не прямым путем.
Проблема возникет когда Lua начинает использовать longjump.
И на стеке могут быть более сложные объекты
Snusmumriken
Вот когда возникнет такая проблема - тогда я тебе напишу, хорошо? : )
Давай решать задачи по мере поступления.
А то ты мне сейчас ещё хаскель объяснишь, хотя я на нём никогда не собирался писать, даже не задумывался.
У меня сегодня уже избыток инфы в голове : )
Alexey
Я просто не считаю нужным добавлять новые объекты в этот самый поток поступающих проблем :)
Alexey
Но как то не всегда получается
Snusmumriken
И не получится, потому что учесть всё - невозможно и никогда не будет возможно, иначе программистов уже давно не было бы : )
Один из самых жутких секретов моего быстрого обучения - не забивать голову ненужной фигнёй и идти исключительно от практики.
Если тема торкнула - можно почитать на досуге, как делает народ, набраться трюков и прочего говна. На досуге = в разгруженное мозгами время.
Если тема не торкнула но как бы нужна - сделать где-то пометку: "Такая-то фигня - такие-то материалы", и вернуться к этому в тот момент, когда снова придётся мутить эту или аналрничную фиговину.
Я так регулярки выучил. С пятого захода, правда, когда в пятый раз обнаружилось, что без них не обойтись.
И шейдеры на glsl, вместе с векторной алгеброй, линалом, сишкой для микрух и прочей фигнёй : )
Alexey
Я регулярки начал учть с теории конечных автоматов :))
Alexey
Как говорится с основ
Snusmumriken
Ты в школе учился тогда, или в институте?
Alexey
Где-то посередине. Полу професиональное училище :)
Alexey
Правда преподы были из институтов
Snusmumriken
Да, кстати, после регулярок, чтобы узнать суть автоматов, оказалось достаточно прочитать про них одну страничку на википедии, и сразу всё стало понятно. Ну, я к тому, что иногда можно узнать практическое применение, а потом потопать в сторону теории, типа "для чего ещё это можно применять".
Snusmumriken
Молодец : )
Надо бы тебя затраллировать какой-нибудь сложной регуляркой, но лень.
B
Гайз
B
что там по алгоритмам? слышал у некого г-на Седжевика есть хорошая книга
ㅤ
Было. Что-то вроде: lib1.lua хочет lib2.lua, а lib2.lua хочет lib1.lua
ㅤ
Обходится, например, подключением одной из библиотек в другой не сразу, а когда она там становится нужна.
mva
это в pil, емнип, рассматривается
ㅤ
require должна полностью исполнить код из файла, и только потом вернуть результат. Если же получается то, что я описал выше то чтобы отработала require "lib1" нужно, чтобы отработала require "lib2", а так как в lib2 подключается lib1, то получается бесконечный цикл из require'ов.
Если сверху в lib2 где-то объявляешь local lib1, а ниже в какой-нибудь функции (где lib1 тебе нужна) вызываешь lib1 = require "lib1", всё должно быть хорошо.
mva
с рекомендациями как это правильно лечить
mva
я сказал "емнип"
mva
я даже не уверен, что я ТАМ это читал
mva
не то чтобы страницу помнить :)
mva
а кроссреквайр-то есть?
mva
ну, тогда странно
mva
а в каких условиях возникает?