Как создать мост QLua-скрипта с другим C++ приложением? Вопрос концепта., Предлагаю такой подход, но есть вопросы.
Пользователь
Сообщений: Регистрация: 18.10.2015
05.12.2025 20:20:37
Я хочу, чтобы внешняя windows-программа, допустим на C++ (но это детали), коннектилась к QLua локально (через named pipes или shared memory или другим IPC-способом) или удаленно по TCP/IP.Концепт такой. В Квике запускается QLua скрипт, который на борту несет C++ модуль подключенный через require. Между ними происходит обмен Lua-C, это в впринципе описано. Пока вопросом тут нет. Внутри этого C++ модуля, допустим встроен named pipes или winsock (для TCP/IP) для IPC межпроцессного взаимодействия. Неважно, что именно, обсуждаем сам подход.
И есть внешняя программа, допустим написанная на том же C++. Она подключается, когда захочет, когда пльзователь запустит эту программу и нажмет, может вообще не подключаться, но QLua-скрипт уже должен быть запущен на тот момент и быть готов принять "подключение". Внутри этого запущенного QLua-скрипта будет что-то вроде:
Код
function doing_stuff()
... здесь данные и вся работа с Lua-C
end
function main()
while is_running do
doing_stuff()
Sleep(100)
end
end
У меня вопрос к строчке
Код
Sleep(100)
Это нормальный вообще концепт в контесет QLua? То есть скрипт с периодичностью 100 мс проверяет, нет ли внешнего подключения, не дёргает ли его кто-то, не просит ли чего-то. Не вставить этот Sleep нельзя, как понимаю. А какая должна быть оптимальная задержка тут? 500, 100, 200, 1000 ?!
И хорош ли сам концепт? Есть ли какие возражения? Внешняя программа на C++ действительно имеется и она должна именно эпизодически подключаться по запросу, не висеть всегда в онлайне.
Пользователь
Сообщений: Регистрация: 30.05.2016
05.12.2025 21:30:57
Под main quik выделяет отдельный поток, ничего страшного если в нем будут тяжелые задачи. Однако, без sleep() одно из ядер процессора будет всегда нагружено на 100%. Задержка не всегда нужна. Например, при использовании библиотеки lua socket поток уже блокируется методами send, receive, и accept (если использовать их в main).
Пользователь
Сообщений: Регистрация: 27.01.2017
06.12.2025 09:52:35
Решения через Socket уже есть: QUIKSharp и QuikQtBridge. Еще есть StockSharp, но много нареканий на него. Также есть RPC вариант - quik-lua-rpc Был еще прямой интерфейс на c++ (но уже давно не поддерживается): qluacpp
По названиям легко найдете репозитории.
Пользователь
Сообщений: Регистрация: 18.10.2015
06.12.2025 17:38:53
C# (шарпы) к сожалению не подходят никак. Максимум подсмотреть общую идею реализации. Писать внешнюю программу придется именно на C++, потому что это плагин к другой программе (четвертой), а там принимают плагины только на C++ или Java (которой я не знаю) по заданному шаблону. Если получится, то получится очень красиво. Но на C# как раз реализовать подобный мост проще всего. Проект QUIKSharp вроде даже видел. На С++ очень мало программистов и примеров. Причем имеется в виду VC++ qluacpp надо бы поикать, не вижу
Пользователь
Сообщений: Регистрация: 18.10.2015
06.12.2025 18:13:53
Нашел qluacp, как вижу требует серьезного причесывания и некоторого обновления. Но хотя бы есть что посмотреть и от чего отталкиваться. Не очень понял с первого взгляда, как именно там устроен IPC (передача данных от Lua-C к программе на C++ и обратно), вроде файлы с диска читает в некоторых примерах, а это очень нехорошо. Но хотя бы пощупать пример. Спасибо. Проще, возможно, даже что-то свое сдалать, максимально легковесное.
На самом деле, скажу больше. В одной из старейших американских торговых платформ, техасских, (существовала с начала 90-х до 2012) именно для американского рынка и местных клиентов (IB еще не существовало, тем более в России), идея написания внешних программ и плагинов была предельно лаконичной. Платформа всегда открывала локальный TCP порт и имела что-то вроде простого telnet-протокола. Все эти getParamEx, разный getInfo по инструментам (или как его там) и даже sendTransaction были вынесены в своего рода простые текстовые запросы по TCP (наподобие telnet- или ssh-команд, только без шифрования, тот же http намного сложнее, если сравнить). И был pdf файлик-приложение, описывающий этот протокол и доступные команды на ввод-вывод. Команд, ксати, немного и все прекрасно описаны. Вполне хватает для многих идей.
Далее пишется по сути даже не плагин к торговой платформе, а обычная клиент-серверная программа-клиент по обычному TCP, даже удаленному, если открыть порты. На любом языке, который в состоянии держать обычные сетевые соединения. По сути Квик реализует то же самое, но hard-coded в рамках встроенного языка, строго в рамках предлагаемой песочницы Lua, из которой "выбираться" предлагается каждому самостоятельно. С одной стороны имеются некоторые преимущества -- намного проще написать GUI-таблицу для квика, даже с "кнопками", с другой стороны гораздо меньше подвижности и масштабируемости. И непонятно, как брать данные, появлется тонна головной боли и ощущение недоделки в смысле архитектуры.
Платформа называлась InstaQuote с логоитипом похожим на Quik, и интерфейс очень похож на Quik. Была выкуплена Bank of America в 2012, переименована в Red-чего-то, извращена индусскими программистами и закрыта со временем.
Пользователь
Сообщений: Регистрация: 27.01.2017
06.12.2025 18:35:15
У qluacpp есть форк
Правда тоже надо пилить напильником. В данном случае проще написать логику через dll на Lua C API.Но если все же смотреть на TCP, то тот же QuikQtBridge () написан на С++, правда с использованием Qt (для сетевой части). И он мне больше нравится, чем QUIKSharp, т.к. у оного сервер, по факту, написан на Lua. Если задача построить только серверную часть, то можно и взять только её.
Пользователь
Сообщений: Регистрация: 18.10.2015
06.12.2025 19:48:29
Задача прогнать небольшие данные из QLua квика во внешнюю C++ программу. Обмен данных между программами. Совершать обмен данных, туда и обратно по запросу из внешней программы. Причем, мне не критично к скорости, да и к объёму.
Где "сервером" будет QLua-скрипт квика, а клиентом - внешняя программа.
Локальный TCP как раз не хотелось бы использовать, потому что придется писать некое продобие протокола на запрос-ответ, и точно не понадобится сеть (всё делается на одной машине localhost 127.0.0.1), хотя на самом деле TCP интерфейс был бы идеальным универсальным вариантом. Поэтому предлагаю себе посмотреть в сторону named pipes. Идея схожа с TCP. Потому что shared memory гораздо сложнее в реализации. На сайте майкрософта для моих целей небольших обменов данных между программами предлагают даже локальные windows-messages. В этом видится определённое извращение, но это вплоне себе несложный и "законный" вариант, как представляется.
Qt тут точно ненужный гость. Предлагаю самый простой и базовый VisualC++ (одной из свежих версий), MFC (да-да, древнюю, но рабочую классику, это база всех windows-программ по сей день, даже Офиса от самого MSFT) и базовых вещей системного windows-программирования. Проблема как в том, что очень много C++ (особенно русскоязычных) в основом под C++ понимают Qt или что-то из мира GNU/Linux, портированное в Windows, а это как раз совсем не нужно. Про базовый MFC они почти ничего и не знают. Я не говорю, что он очень нужен здесь, я описываю положение вещей. Даже просмотренный qluacpp пропитан Линуксом и некоторым фундаментальным непониманием автора некоторых базовых вещей. То есть та еще поделка на коленке. Поэтому появился , костыль на костыль. Ну что ж, посмотрим, что там можно причесать или оттяпать. Если что-то вообще можно.
Пользователь
Сообщений: Регистрация: 20.03.2023
06.12.2025 22:25:18
Цитата
A.T. написал: Причем, мне не критично к скорости, да и к объёму.
Тогда не понятно, чем Вас файлы не устраивают, особенно в RAM диске. Это даже не потребует dll для QLua. А протокол на запрос-ответ понадобится в любом случае.
Пользователь
Сообщений: Регистрация: 18.10.2015
07.12.2025 01:32:18
Потому что это совсем колхоз, архитектурно неправильно. Я еще должен выделять специальное место в системе, как загашник... Когда существует официальная связка Lua-C (описанная в книге Иерусалимского), в детали не вникал и данные не гонял, но тестовый запуск уже получился, это есть.
Тем более есть мысли применить такой мост Lua-C <=> VC++ (MFC, скорее всего) и в другом месте, не только как узкоспециальный плагин на раз.
И потом, что значит "особенно в RAM диске"? Мне еще сторонний витруальный диск ради этого создавать? Какими-то сторонними драйверами? И запускать/пересоздавать его, заботиться после каждой перезагрузки. Который будет мешаться в системе в повседневных делах. У меня не только квик, у меня и другие развлечения есть. То есть это даже не костыль, это хуже. Настолько временное решение, что лучше о нем не думать. На сайте Майкрософта висит готовый пример для named pipes. И не только для него.
Насчет протокол на запрос-ответ понадобится в любом случае, тут спасибо за заметку. Пока думаю об этом в первом приближении. Думаю отделаться простыми переменными, if-elsами, сравнениями и кейсами. Хотя это не дело, если делать нормальный переносимый мост. Но для себя сгодится и так. Наверно. Тут не знаю, опыта в создании протоколов нет.
Пользователь
Сообщений: Регистрация: 30.01.2015
07.12.2025 16:22:51
Цитата
A.T. написал: Потому что это совсем колхоз, архитектурно неправильно. Я еще должен выделять специальное место в системе, как загашник... Когда существует официальная связка Lua-C (описанная в книге Иерусалимского), в детали не вникал и данные не гонял, но тестовый запуск уже получился, это есть.
Тем более есть мысли применить такой мост Lua-C <=> VC++ (MFC, скорее всего) и в другом месте, не только как узкоспециальный плагин на раз.
И потом, что значит "особенно в RAM диске"? Мне еще сторонний витруальный диск ради этого создавать? Какими-то сторонними драйверами? И запускать/пересоздавать его, заботиться после каждой перезагрузки. Который будет мешаться в системе в повседневных делах. У меня не только квик, у меня и другие развлечения есть. То есть это даже не костыль, это хуже. Настолько временное решение, что лучше о нем не думать. На сайте Майкрософта висит готовый пример для named pipes. И не только для него.
Насчет протокол на запрос-ответ понадобится в любом случае, тут спасибо за заметку. Пока думаю об этом в первом приближении. Думаю отделаться простыми переменными, if-elsами, сравнениями и кейсами. Хотя это не дело, если делать нормальный переносимый мост. Но для себя сгодится и так. Наверно. Тут не знаю, опыта в создании протоколов нет.
Расскажу свой опыт решения этой задачи. -------------------- Сначала кратко повторю то, что уже недавно и давно писал на форуме с тестами. ------------------------ Во-первых замечу если ставите sleep ( я использую event) то задержка передачи данных будет равна задержке sleep. можно поставить sleep(10) этого достаточно чтобы поток не грузил ядро впустую. Можно даже поставить sleep(1) но задержка реально будет примерно 10 ms - это квант OS. -------------------- Так вот обмен через файлы это самое простое (примерно 10 операторов) и задержка не более 15 ms ---------------------- Я использую для обмена между процессами File Mapping При этом если использовать event, то задержа примерно в 100 раз меньше, чем при обмене через файлы. Для обмена между скриптами т е потоками main в разных скриптах QUIK , использую глобальные переменные. При этом, если использовать event, то задержка примерно в 1000 раз меньше, чем при обмене через файлы (3-5 мкс) ---------------------------- Эти методы самые быстрые. -------------------
Пользователь
Сообщений: Регистрация: 30.01.2015
07.12.2025 16:27:54
...замечу, глобальные переменные не луа, а среды исполнения приложения.