LINUX.ORG.RU

Qt приложение с ядром на другом языке

 , , ,


1

6

На плюсах писать боль - хочется что-то более человеческое. Но приложение будет GUI, а значит Qt. Тут обсуждать нечего.

Нужно, каким-то образом, наладить общение между двумя языками в пределах одного ПК. Допустим с Rust.

Пробовал FFI (при использовании языка с GC - отпадает) - боль. Ибо получается жирная(много boilerplate кода) прослойка вида: rust -> c-api -> mylib.h -> С++ враппер. Также теряются все гарантии языка.

Ну и конвертации типов тоже не бесплатны. Напоминаю, что QString - UTF-16.

RPC, любой, - тоже затратно. Ибо сериализация/десериализация может быть затратной. А данных довольно много.

Пример: есть база с кучей записей. Нужно отобразить их в проге. Ну пусть тысячу строк. Передавать их через RPC - бред. Слишком медленно. Намного быстрее из Qt подключится к базе и забрать нужные данные. Но тогда пропадает смысл в «ядре» на другом языке.

То есть Qt будет использоваться чисто как GUI. Вся логика будет «ядре». Проблема в передачи больших объемов данных.

Как решить данную задачу? Уверен, что кто-то с таким сталкивался.

★★★★★

Ибо сериализация/десериализация может быть затратной

А ты не используй затратную. Есть очень быстрые штуки, https://capnproto.org/ например. Ну и конечно отправлять данные надо «лениво» - только то что нужно увидеть на экране

annulen ★★★★★
()

Напоминаю, что QString - UTF-16

Использовать исклдючительно для гуишных строк, т.е. тех которые будут виджетами рисоваться. Любые другие строковые данные QByteArray c ascii или utf8

annulen ★★★★★
()

На плюсах писать боль
Пробовал FFI (при использовании языка с GC - отпадает) - боль
Напоминаю, что QString - UTF-16.
RPC, любой, - тоже затратно

https://anekdot.d3.ru/utochka-i-lebedi-469486

Кстати, не любой RPC подразумевает сериализацию.

Передавать их через RPC - бред. Слишком медленно. Намного быстрее из Qt подключится к базе и забрать нужные данные.

Вообще-то в Qt эти данные попали фактически по RPC, и на скорость никто не жаловался.

Как решить данную задачу? Уверен, что кто-то с таким сталкивался.

Ядро на другом языке пишут тогда, когда профит очевиден и значителен. Если в твоем случае его нет, то вопрос закрыт.

tailgunner ★★★★★
()

Прежде чем говорить что-то о медленности rpc попробуй запустить rdp клиента приконнекченного к локальному rdp серверу. Если такая скорость передачи данных тебя не устраивает, можно и быстрее чай, лет 20 назад разрабатывалось.

pon4ik ★★★★★
()

А данных довольно много

Совершенно субъективная постановка вопроса, даже порядок не привёл.

Как бы много не было данных, gui одно из самых медленных устройств ввода вывода на любой платформе, пока речь не идёт об аппаратном ускорении. Точно медленнее чем сеть, а уж тем более всякие fifo и шарные памяти.

pon4ik ★★★★★
()

Ибо сериализация/десериализация может быть затратной

Не смеши мои тапки, в рамках одной машины ты можешь хоть сырыми структурками в сокет пулять. Главное pragma pack(1), и понеслась

А данных довольно много.

И тут ты такой открываешь для себя shared memory.

Хотя постой, криворучка вроде тебя не осилит столько ансейфных операций. Тогда остается только веб-интерфейс. Ну и ядро на похапе, само собой.

anonymous
()

Ну если тебе настолько нечего делать и не жаль своего времени, то пили привязку Rust к Qt:

https://github.com/rust-qt/cpp_to_rust

А так, можно просто вынести часть логики в библиотеку и использовать ее из С++ кода.

anonymous
()

Пробовал FFI (при использовании языка с GC - отпадает) - боль. Ибо получается жирная(много boilerplate кода) прослойка вида: rust -> c-api -> mylib.h -> С++ враппер. Также теряются все гарантии языка.

Да ну, что-то ты не так делал. Просто экспортируешь функцию, в С++ делаешь dlsym и вызываешь. Да, лишний код, но если грамотно выписать интерфейс, то его будет минимум.

anonymous
()

У Qt свои «плюсы», не такие уж и страшные. Это тебе я говорю (мою любовь к «плюсам» ты, возможно, знаешь).

То есть Qt будет использоваться чисто как GUI. Вся логика будет «ядре».

Мне кажется, что это иллюзия, хотя я не приведу сильных аргументов в защиту. GUI - это сложно. Если у тебя там не ИИ, то тебе придётся по полной потратить силы на GUI и не стоит считать эту задачу второстепенной.

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

А вообще - технология клиент-сервер, сокеты, асинхрощнина, обмен сообщениями. Отдельный тред может быть задействован для диспетчеризации сообщений. Будет ли это медленно - поймёшь по ходу дела (скорее всего, не будет). Я вот раскраску в редакторе передаю из лиспа в tcl/tk через сокеты, да и вообще, каждая операция в текстовом редакторе дублируется на стороне сервера и клиента. Сначала было нормально, потом улучшил и стало медленно. Руки не дойдут поправить.

Главное в этой технологии - надёжность клиента и сервера не снижаются, т.к. нет FFI. Клиент и сервер каждый написаны на одном языке и это здорово. Гарантии от твоего ржавого остаются.

Плюс легко трассируется и логгируется весь обмен. Ну и всякие приятные мелочи, типа работы через VPN с размещением сервера где-то в облаках (хотя в моём случае так не выйдет, т.к. и клиент, и сервер должны видеть одну и ту же файловую систему).

Если сокеты не подходят, попробуй разделяемую память.

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 2)
Ответ на: комментарий от den73

GUI не так страшны как приложения с могучей логикой. Вот там беда, но я бы использовал Qt везде, где только можно, чтобы не возиться с кучей разных технологий, если нет веских причин не делать этого.

peregrine ★★★★★
()
Ответ на: комментарий от den73

т.к. и клиент, и сервер должны видеть одну и ту же файловую систему

Если очень хочется, можешь в клиент передавать всю информацию о файловой системе на сервере.

peregrine ★★★★★
()
Ответ на: комментарий от annulen

Ну так в расте у меня Vec<String>, а в Qt - QStringList. Совсем разные вещи. Вот эта конвертация и будет дорогой.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

Профит в том, чтобы не писать на C++.

Вообще-то в Qt эти данные попали фактически по RPC, и на скорость никто не жаловался.

Технически - да. А так добавляется ещё один уровень. Нужно тестить, но сомневаюсь что чтение базы в «ядре», а потом отправка в GUI, будет быстрее, чем чтения сразу из GUI.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Главное pragma pack(1), и понеслась

Я что, больной сырые данные пересылать? У меня есть нормальная структура в одном ЯП и нужно получить такую же/аналогичную в другом. Я не собираюсь кастовать сырые данные.

Тогда остается только веб-интерфейс.

Кто о чём, а вшивый о бане.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Биндинги не дают нужных мне возможностей.

RazrFalcon ★★★★★
() автор топика
Последнее исправление: RazrFalcon (всего исправлений: 1)
Ответ на: комментарий от peregrine

Да понятно, могу, просто это доп. трудозатраты, а ресурсов мало.

den73 ★★★★★
()
Ответ на: комментарий от anonymous

Просто экспортируешь функцию, в С++ делаешь dlsym и вызываешь.

Ну и зачем мне сишный интерфейс в плюсовом коде?

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от den73

Я на Qt уже лет 8 пишу и знаю их прелести. Именно поэтому и хочу свалить куда-то.

GUI будет только отображать данные. Понятное дело, что там минимальная логика тоже будет. Но не вся.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от den73

В данном случае язык «ядра» роли не играет. Ибо FFI маловероятен.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

это потому что ты придумал муйню и теперь от неё страдаешь. так и будешь страдать, пока ты не поймёшь, что сама идея в корне неправильная. не умеешь писать на плюсах - не пиши. вот и всё.

Iron_Bug ★★★★★
()
Ответ на: комментарий от den73

Померят что? Мне хочется какой-то враппер, что ли.

Допустим у меня jsonrpc. Не буду же я сам перекладывать данные туда сюда... У того же раста есть serde, а вот для C++ аналога не знаю.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Ну, ты померяй.

Просто вывод неформатированного текста в твой любимый элемент вывода текста по мере поступления данных, по сравнению с тем же tcp (и даже правильно сделанной подсистемой логгирования), через n мегабит может начать отставать на минуты, и сиё можно будет наблюдать невооружённым глазом.

Как ты думаешь - у тебя при dd if=/dev/sda, где будет узкое место? Что то мне подсказывает, что упрётся оно таки в гуй эмулятора терминала, хотя он несомненно сложнее чем обычный элемент по отрисовке текста.

pon4ik ★★★★★
()
Последнее исправление: pon4ik (всего исправлений: 1)
Ответ на: комментарий от pon4ik

Пруфы будут?

Заливать мегабайты текста в виджет, предназначенный для отображения пары строк - это сильно.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Профит в том, чтобы не писать на C++.

Профит - это разница между выгодой писать не на Си++ и расходами (трудозатратами, не машинному времени) на организацию взаимодействия.

Нужно тестить, но сомневаюсь что чтение базы в «ядре», а потом отправка в GUI, будет быстрее, чем чтения сразу из GUI.

Сомневаешься? Ну окей %)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Я тестил JSON-RPC. Тормоза были космические.

Понятное дело, что лучше всякие protobuf и подобные, но до них руки не дошли.

Вопрос-то к тем, кто уже подобное делал.

Ну а про профит - это личный проект. Что хочу - то и ворочу. Сроков нету.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от den73

Есть такой, подающий надежды, редактор-фреймворк - xi-editor. Он использует jsonrpc через stdin/out. Автор говорит, что не тормозит.

Но у него пакеты не больше сотни байт.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Я тестил JSON-RPC. Тормоза были космические.

М.б. стоит глянуть в сторону protobuf/grpc?

anonymous
()
Ответ на: комментарий от RazrFalcon

Ну так в расте у меня Vec<String>, а в Qt - QStringList.

Нафига тебе в гуи QStringList, у тебя будет модель, или наоборот строки раскиданные по разным виджетам. Так что от сохранения контейнера типа «вектор» проку все равно бы не было. А QString получить из utf8 - не такая уж дорогая операция, там заоптимизировано все. Или можно в базе прям в UTF16 хранить и в нем же вычитывать и передавать гую, не заглядывая что внутри этих строк. Немного больше трафика на юникс-сокете, зато никаких конверсий

annulen ★★★★★
()
Ответ на: комментарий от RazrFalcon

Ну не знаю за json-rpc, я своё писал. Оптимизацией именно трансформации не запаривался, но асинхронностью озаботился. Правда, race conditions до сих пор не все отловил.

den73 ★★★★★
()
Ответ на: комментарий от RazrFalcon

Ну можешь хоть кастомный сделать, сути это не поменяет, пока оно не будет на opengl/directx (да и там тоже не факт что выйдет).

Пруф мне делать лень, если поверишь на слово, то вот например история - на локалхосте по tcp из эмулятора сервера предаются данные в ответ на запрос. На каждый запрос(200-1400 байт), выводится шестизначное число и перевод строки в элемент static text(или как оно там в winapi называется), затем сервер выдаёт ответ (обработку запроса тут в расчёт можно не брать, т.к. она ничтожно мала по сравнению с i/o). Начиная от миллиона запросов, после получения всех ответов от сервера, гуй эмулятора рисует ещё около сорока секунд. Гуй сервера запилен mfc, т.е. по сути не смотря на своё уродство, максимально тонкая обёртка над системным api.

Обусловлено это тем, что, что помимо собственно отрисовки (на это слава ктулху спец железо придумано), gui поток ожидает и так же обрабатывает события ввода вывода от пользователя. А теперь включи мозг, и подумай, как бы ты сделал поток который и рисует и читает устройства?

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

А теперь включи мозг, и подумай, как бы ты сделал поток который и рисует и читает устройства?

В винде это было бы (я думаю) окно и цикл обработки сообщений, и я не думаю, что этот поток когда-либо спит, если очередь сообщений непуста. Взаимодействие с уйстройством обрабатывает ОС в другом треде. В линуксе, скорее всего, несколько тредов под разные взаимодействия (можно посмотреть, как сделан tk, хотя автору темы проще посмотреть в Qt наверное).

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от pon4ik

пока оно не будет на opengl/directx

У вас очень странное представление о GUI. Аппаратное ускорение никаким образом не ускорит отрисовку таблицы/текста. Сложные анимации может будут плавнее, но не более.

или как оно там в winapi называется

Так мы про Qt или GUI в целом? Винапи тормоз - это не новость.

gui поток ожидает и так же обрабатывает события ввода вывода от пользователя

У меня сейчас включено с десяток GUI приложений и проц фактически простаивает. Ну и кто, что жрёт?

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от den73

Всё правильно ты думаешь, везде есть очередь, вопрос в скорости разгребания. Соль в том, что все гуй потоки работают примерно как boost::asio::io_service::run. Все действия по работе с элементами gui происходят в коллбэках, а в свободное время разгребается очередь сообщений от пользователя.

А теперь тонкий момент. Сколько нужно ожидать события от пользователя, что бы потом пойти продолжить исполнять колбэки, что бы гуй «не тормозил»?

pon4ik ★★★★★
()
Ответ на: комментарий от RazrFalcon

Так мы про Qt или GUI в целом? Винапи тормоз - это не новость.

Я не сильно слежу за пятым, т.к. давно не делаю гуй. Но, на четвёртом в бэкэнде было имено winapi. А то что оно тормоз - это конечно же в тебе говорит святая вера а не увиденные результаты бенчмарков. Если брать актуальные ядра, то даже сетевое api сравнимо с онтопиком, хотя местами проигрывает по тонкости настройки. Выглядит оно как Г-но это да, но не более того.

У меня сейчас включено с десяток GUI приложений и проц фактически простаивает. Ну и кто, что жрёт?

Так оно спит...

В общем посмотри как реализуется основной цикл gui приложения, не важно под каким api, главное не под обёрткой.

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

В общем посмотри как реализуется основной цикл gui приложения, не важно под каким api, главное не под обёрткой.

Или, если хочется много лишних деталей, посмотри как в Qt реализован метод QApplication::run

pon4ik ★★★★★
()

На плюсах писать боль - хочется что-то более человеческое. Но приложение будет GUI, а значит Qt. Тут обсуждать нечего.

Раз выбран Qt, то С++. Есть ещё конечно PyQt, но тебя он как-то не интересует. Остальные огрызки из https://wiki.qt.io/Language_Bindings не хочется и обсуждать.

Причина: Qt --- это С++ либа. С++ --- это язык сам в себе. Не один ЯП не понимает С++.

Когда в Qt будет ещё и C++XX, то огрызков останется меньше.

rust -> c-api -> mylib.h -> С++ враппер.

Это как? С каких пор это в «Представление» так жёстко впихивают данные, когда оно само должно их запросить и отобразить.

Профит в том, чтобы не писать на C++.

Простой запрос на Rust GUI Выводит на http://relm.ml/relm-intro

Вот тут профит.

Причина: GTK базируется на GObject, который чисто Си задродство. Но его легко обернуть и использовать в любом ЯП.

AlexVR ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.