Alexander (Все сообщения пользователя)

Выбрать дату в календареВыбрать дату в календаре

Страницы: Пред. 1 2 3 4 5 6 След.
Как запустить скрипт qlua из командной строки?
 
Цитата
nikolz написал:
VMLua - это программа и она запускается вызовом lua_pcall, в которой вызывается
Где в этой функции вызов lua_pcall?
Как запустить скрипт qlua из командной строки?
 
Цитата
nikolz написал:
Т е запускаю сколько мне надо новых VMLua внутри КВИКА и КВИК ничего в них не контролирует.
И тут даже вообще не понятно зачем запускать сколько надо новых VMLua внутри КВИКА если сам квик интерпретирует скрипт уже и он может их(скриптов) интерпретировать сколько угодно.
Как запустить скрипт qlua из командной строки?
 
Цитата
nikolz написал:
VMLua - это программа и она запускается вызовом lua_pcall, в которой вызываетсясобственно VMLua  - эта функция  Вот ее тест из sorce code Lua 5.4
Ну тут всё правильно написали про VMLua, что она именно ЗАПУСКАЕТСЯ, а ранее писали, что VMLua РАБОТАЕТ как самостоятельная единица.
Как запустить скрипт qlua из командной строки?
 
Цитата
nikolz написал:
Я точно также запускаю свои скрипты внутри КВИКА в потоках из пула.Т е запускаю сколько мне надо новых VMLua внутри КВИКА и КВИК ничего в них не контролирует.
Можете по пунктам расписать что Вы тут конкретно имели ввиду. Что за пул потоков? Кто его создаёт? Скрипт внутри квика, библиотека dll? Ваш код на C++ интерпретирует Ваши же скрипты?
Как запустить скрипт qlua из командной строки?
 
Пока ясно, что родной интерпретатор lua53.exe с сайта lua.org не катит. Он сам интерпретатор, использует lua53.dll, и квик интерпретатор, который тоже использует lua53dll. Но квик подгружает свою qlua.dll и наш скрипт использует её функции внутри себя, когда квик интерпретирует наш скрипт. А если я извне запущу через lua53.dll свой квиковский скрипт и подключу квиковскую qlua.dll? Чтобы использовать её функции. У меня будет окружении QLUA? Ну там _G с её элементами? Может так можно из вне запустить свой скрипт? Ну для начала скажем без коллбэков к примеру хотя бы. Так как они наверняка не будут в таком случае работать. Квик их обрабатывает сам при загрузке скрипта.
Как запустить скрипт qlua из командной строки?
 
Цитата
swerg написал:
По пункту б) как пример для начала есть  https://github.com/swerg/qlua-exe Для связи между процессами есть библиотека lua_share  https://quik2dde.ru/viewtopic.php?id=306 Опять же можно взять её исходники за основу.
Это пока не смотрел. Посмотрю как время будет, отпишу.
Как запустить скрипт qlua из командной строки?
 
Цитата
swerg написал:
Сделать можно , если наладить связь между процессами а) QUIKа, с одной стороны б) и собранным вами запускаемым exe-шикном, который будет уметь подхватывать Lua скрипты и выполнять их.
Наладить связь между моим exe-шником и скриптом КВИКА конечно можно. Тут думаю проблем нет никаких. Способов достаточно. Тут вообще если такой подход использовать, то по сути этот Lua практически и не нужен. Достаточно всё, что надо писать на C++(dll, exe), а скрипт внутри Lua использовать чисто для связи с (dll, exe) как транспорт, ну транзакции естественно через QLua. Подхватывать скрипты, и выполнять их. Выполнять можно. Что значит подхватывать? Где? Или откуда? Что имелось ввиду?
Как запустить скрипт qlua из командной строки?
 
В сообщении выше надо читать в начале НЕ "Вы писали, что виртуальная машина КВИКА работает сама по себе и ей просто достаточно "скормить" скрипт и он будет ей исполнен", а "Вы писали, что виртуальная машина Lua работает сама по себе и ей просто достаточно "скормить" скрипт и он будет ей исполнен"
Как запустить скрипт qlua из командной строки?
 
Цитата
nikolz написал:
Я точно также запускаю свои скрипты внутри КВИКА в потоках из пула.Т е запускаю сколько мне надо новых VMLua внутри КВИКА и КВИК ничего в них не контролирует.более того, можно вообще запустить вне квика VMLua и в нем скрипт чего-угодно, а необходимые данные передавать из квика с помощью библиотеки QLUA, которая собственно и сделана для передачи данных из терминала в скрипт луа.
Что так Вы запускаете свои скрипты КВИКА внутри пула своих потоков вы только сейчас написали, до этого Вы писали, что виртуальная машина КВИКА работает сама по себе и ей просто достаточно "скормить" скрипт и он будет ей исполнен. Из Вашего объяснения вывод был получен такой, что эта виртуальная машина это самостоятельная единица самого некоего Lua процесса, который работает сам по себе независимо от КВИКА, теперь выясняется, что так и есть как я писал, что КВИК таки сам интерпретирует скрипты, и Вы пишете, что делаете тоже самое. Так зачем тогда писали в духе, что типа не КВИК интерпретатор?
Далее, да конечно можно запустить сколь угодно таких VMLua вне КВИКА. Передавать данные из КВИКА им с помощью библиотеки QLUA, что тут имеется ввиду?  Каким именно образом? Какие именно функции QLUA Вы имеете в виду? Так то, я могу и не Lua скрипты запускать, а процессы на C++, например написанные и принимать данные от КВИКА любым доступным способом Windows.
Как запустить скрипт qlua из командной строки?
 
Разработчики ПО Quik, прошу ответить, начиная отсюда: https://forum.quik.ru/messages/forum10/message70393/topic6175/#message70393
Как запустить скрипт qlua из командной строки?
 
Разработчики ПО Quik, прошу ответить.
Как запустить скрипт qlua из командной строки?
 
Цитата
nikolz написал:
Но поясню что не так в вашем понимании.
Я конечно пока не настаиваю, но вынужден не согласиться с некоторыми Вашими объяснениями. Для начала:
1) Понятия конечно есть м/у компилируемыми и интерпретируемыми языками программирования. Грубо: компилируемые - исходный код -> asm код -> obj код -> сборка линкером -> выполняемый код(exe, dll)(процессором непосредственно в памяти с передачей на него управления). Интерпретируемые грубо: исходный код -> байт код -> выполнение в своей собственной среде байт кода.
2)
Цитата
nikolz написал:
В программе КВИК запущена программа VMLua. VMLua работает сама по себе, исполняя загружаемые в нее скрипты. Т е разработчики КВИК не разрабатывали VMLua, а взяли готовый код и запустили его внутри своей программы.
Как quik запустил VMLua? Как Вы себе это представляете?
3)
Цитата
nikolz написал:
В нее можно грузить любой скрипт на луа и она будет его исполнять.
Как Вы себе представляете как quik грузит код в "запущенную им VMLua?
4)
Цитата
nikolz написал:
Чтобы передать VMLua данные из терминала QUIK, разработчики написали библиотеку QLUA на СИ и таким образом организовали обмен информацией между двумя процессами , один из которых на VMLua.
Тут как бы да, а может и нет. Делают ли загрузку скрипта функции из qlua.ll или это делает сам info.exe или функции из других dll, имеющиеся в quik-е мне не известно, но в qlua.dll полагаю, что находятся функции для торговли и работы с брокером и для получения данных с биржи, т.е. это функции qlua, что описаны в документации quik-a. Quik не тупо передаёт скрипт на выполнение как единое целое в VM - типа загрузил, передал и всё,- скрипт работает сам по себе в среде VMLua, не так всё.
5)
Цитата
nikolz написал:
чтобы делать это автоматом надо  написать соответствующий скрипт для виртуальной машины либо для планировщика задач с использованием библиотеки функций манипуляции с экраном. В скриптах это делается хуками.  Я делал это на AutoIt.
Это не то, что хотелось бы,поскольку это всего лишь будет просто автоматизация обычного процесса пользователя по загрузке скрипта, т.е. тоже самое, что делаем руками для загрузки скрипта, но только автоматом через скрипт(AutoIt).

  А теперь попробую объяснить более подробно почему я так думаю как написал выше, а не так как Вы написали. Для этого рассмотрим как я представляю себе VMLua и как её использует quik. Но сначала посмотрим как интерпретирует Lua код обычный Lua. На оф. сайте Lua весь интерпретатор Lua - 4 файла(lua53.dll, lua53.exe, luac53.exe и wlua53.exe).
Как мы запускаем скрипт на выполнение в среде Lua? Мы запускаем lua53.exe и передаём ему в командной строке при запуске имя нашего .lua файла и видим результат его работы. Как работает Lua53.exe? Она открывает наш файл, чтобы его читать. Он его читает и разбивает на логические куски согласно синтаксису языка, проверяя при этом синтаксис - парсит, далее каждый кусок он компилирует в свой байт код(lua_load, luaL_loadstring), потом он выполняет последовательно каждый кусок(lua_pcall). Это тоже как бы грубое описание, но суть отражает, без нюансов. Т.е. lua53.exe это всего лишь загрузчик и обработчик, само выполнение реализуется функциями внутри lua53.dll. То есть что мы имеем? Мы не имеем конкретно работающую в прямом смысле слова VMLua. Мы имеем загруженную библиотеку lua53.dll, которая содержит в себе много чего из функций, некоторые из которых осуществляют компиляцию, некоторые - выполнение компилированного кода. Нет такого, что lua53.exe взял наш скрипт и просто тупо скормил его некоему работающему процессу VMLua. Хотя конечно можно было бы сказать и так, что допустим такой процесс есть как отдельный, но тогда lua53.exe грузит файл скрипта и передаёт его этому процессу, а этот процесс уже делает то, что я описал выше, но от этого суть не меняется.
  Так вот идём дальше. Как мне видится работа quik в плане обработки скриптов. У quik в рабочей папке есть библиотеки lua51-54.dll, там собственно и реализована VMLua и функции Lua. Quik грузит наш скрипт и ничего никому не скармливает в прямом смысле слова, а начинает сам выступать в качестве интерпретатора Lua скрипта по вышеописанной мной схеме, при этом он использует функционал заложенных в lua51-53.dll функций для компиляции и выполнения компилированного байт кода. Почему так? Потому как Quik помимо работы скрипта так же делает и "свою" работу и в тоже время он может "контролировать" выполнение скрипта, так как наш скрипт не выполняется отдельно сам по себе в какой-то VM, а quik выполняет его частями, тем самым quik может и "позволить" организацию коллбэк функций, отсюда кстати и многие проблемы непредвиденного характера, так как по сути скрипт не работает как непрерывно целое в некоей среде, при некоторых условиях возможно, что quik может прерывать его выполнение если "так надо", хотя main() скрипта обрабатывается в отдельном потоке quik-а, это не исключает этого. Ниже для подтверждения моих мыслей простой интерпретатор Lua, который делается элементарно, думаю как-то так работает и quik, т.е.по такому же принципу:

Листинг 25.1. Простой автономный интерпретатор Lua
#include <stdio.h>
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
int main (void) {
char buff[256];
int error;
lua_State *L = luaL_newstate(); /* открывает Lua
*/
luaL_openlibs(L); /* открывает стандартные библиотеки
*/
while (fgets(buff, sizeof(buff), stdin) != NULL) {
error = luaL_loadstring(L, buff) || lua_pcall(L, 0, 0, 0);
if (error) {
fprintf(stderr, "%s\n", lua_tostring(L, -1));
lua_pop(L, 1); /* выталкивает сообщение об ошибке из стека
*/
}
}
lua_close(L);

Поэтому хотелось бы услышать ответы разработчиков по заданным мной вопросам. Может быть я и не прав, а прав на самом деле nikolz, я не спорю, а просто хочу понять правильно ли я понимаю организацию работы скриптов в quik или нет.
Как запустить скрипт qlua из командной строки?
 
Я понимаю, что любой скрипт Lua можно выполнить используя родной интерпретатор Lua - lua.exe, нужную версию которого можно скачать с официального сайта. С этим всё просто и понятно. Это работает, когда мы пишем Lua программу, работающую самостоятельно(в данном случае отдельно от квика). Когда мы запускаем скрипт Lua в квике, то как я понимаю это происходит приблизительно так. Квик(info.exe наверное) загружает наш скрипт, построчно его читает, используя функции из библиотеки, например lua53.dll, выполняет прочитанные строки из нашего файла скрипта(используя pcall или что-то подобное), короче он сам интерпретирует наш скрипт построчно, используя нужную библиотеку Lua. Так же разработчики написали свою библитотеку qlua.dll, в которой реализовали все свои функции для торговли и получения информации от брокера, котировки с биржи и прочее. Так же, поскольку сам квик построчно выполняет скрипт, он чередует работу самого себя с работой по интерпретации скрипта, благодаря чему сделана возможность коллбэк функций для скрипта. Может что-то и не так понимаю. Если что-то не так - прошу разработчиков ответить так это или нет. А в связи с этим сам вопрос: есть ли возможность запустить мой скрипт qlua, используя в командной строке, что-то типа info.exe myscrypt.lua, при работающем квике и подключённом к серверу квик? Для чего это нужно? Поставил Visual Studio Code. Хочу настроить его для написания скриптов Lua. Там есть возможность установки плагина для запуска скрипта из редактора - что-то типа Code Runner. Он позволяет настроить запуск скрипта используя интерпретатор в виде программы, которая запускается в командной строке, принимая в качестве параметра запуска файл скрипта. Прошу кто знает или самих разработчиков ответить возможно ли организовать такое? Было бы очень удобно. Пишем в редакторе со всеми его возможностями. Запускаем скрипт прямо в редакторе на выполнение. Скрипт запускается через запуск интерпретатора квика, использует все возможности - функции из qlua библиотеки, скрипт делает вывод в терминал во время работы нужной информации по ходу работы скрипта. Или как-то подобное можно организовать по другому? Можно ли использовать стандартный интерпретатор lua.exe для запуска скрипта, но как тогда связать работу скрипта с билиотекой qlua.dll?. В любом случае нужен запуск скрипта из Visual Studio Code и чтобы скрипт нормально работал так как будто он работает в самом квике.
Выгрузка библиотек
 
Цитата
nikolz написал:
nikolz
Очень хочется познакомиться с этой темой по ffi поближе, но пока времени на это нет. Постараюсь по возможности потом как-нибудь в неё вникнуть, думаю будут и вопросы, но уже задавать их буду наверное в соответствующей теме.
Не могу заставить работать функцию Subscribe_Level_II_Quotes()
 
Цитата
Станислав написал:
Цитата
Alexander написал:
Что за ерунда такая?
Все так как и должно быть. Просто вы не учитываете, что процедура Subscribe_Level_II_Quotes выполняется асинхронно и требует значительного времени на выполнение.
Ставил задержку после подписки и перед чтением стакана в 1 минуту - Котировок нет. Но я вот только что нашёл как надо. Задержка по любому нужна на срабатывание. Но нужна обязательно функция main, а все действия делаем в отдельной функции и задержку ставим 100 мс хоть внутри этой функции хоть в main, тогда корректно можно дождаться срабатывания чтения стакана. А по поводу асинхронно, то разработчики об этом должны писать в документации и так же указать, что никакие задержки не сработают если не будет функции main()
Так же возможно и вообще всё делать чисто в main() и с задержкой на срабатывание - наверняка сработает, но я не проверял. Просто быстро накатан был скрипт для проверки без main(). И кто бы знал, что одни и те же действия будут работать по разному с main() и без? А началось всё с того что в рабочем скрипте не было задержки и стакан не читался, сейчас поставлю и посмотрю на результат.
Не могу заставить работать функцию Subscribe_Level_II_Quotes()
 
Что вообще происходит с заказом стакана котировок кто-нибудь может пояснить? Если есть открытый стакан, то никаких проблем нет. Проверка на подписку функцией  IsSubscribed_Level_II_Quotes всегда показывает, что подписка есть, т.е. она возвращает true и стакан нормально читается через getQuoteLevel2. Но если стакан не открыт в квике, то если запустить скрипт:

ClassCode = "SPBOPT"
SecCode = "RI107500BF3"

if (not IsSubscribed_Level_II_Quotes(ClassCode, SecCode)) then
    message("Подписываемся на стакан по инструменту")
    if Subscribe_Level_II_Quotes(ClassCode, SecCode) then
        message("Подписались на стакан по инструменту")
    end
    Subscribed = true
end

quotes = getQuoteLevel2(ClassCode, SecCode)

if quotes.bid and quotes.bid[ 1 ] then
   message("Есть котировки")
else
   message("Котировок нет")
end

if Subscribed then
   message("Отписываемся от стакана по инструменту")  
   Unsubscribe_Level_II_Quotes(ClassCode, SecCode)
end

то по очереди выводятся сообщения в следующем порядке:

Подписываемся на стакан по инструменту
Подписались на стакан по инструменту
Котировок нет
Отписываемся от стакана по инструменту

И запускай хоть сто раз - будет то же самое! Хоть и подписались на стакан, а читать нечего!

Далее делаем следующее - последние 4 строчки закомментируем, т.е. в любом случае отписку от стакана не делаем. Тогда если запустить такой скрипт, то вывод будет такой:

Подписываемся на стакан по инструменту
Подписались на стакан по инструменту
Котировок нет

Но если запустить этот же скрипт теперь второй раз, то вывод будет:
Есть котировки

И потом хоть сто раз запускай - вывод будет - Есть котировки

Что за ерунда такая? Чтобы нормально читать стакан при подписке = true надо завершить скрипт и запустить его заново, при этом не отписываясь при первом запуске? Как нормально подписаться и нормально сразу читать стакан? Мне нельзя скрипт останавливать. Ранее работал со стаканами - всё нормально подписывалось и читалось сразу. Но там всё в цикле было и проверка на подписку и подписка если нет подписки, потом чтение стакана. Мне надо один раз подписаться и чтобы потом в цикле читать стакан. А то выходит полный бред какой-то - подписался нормально, Subscribe_Level_II_Quotes(ClassCode, SecCode) вернула true, а стакан не читается.
Выгрузка библиотек
 
Цитата
nikolz написал:
Цитата
Alexander написал:
 
Цитата
nikolz  написал:
ссылка для скачивания  dll с функциями выгрузки
  https://transfiles.ru/cp4bi  

выгрузить на Lua5.3 :
require"nkDDD"
nkDDD.freeDLL( имяВыгружаемойDLL)

для выгрузки на СИ  функция
void nkfreeDLL(char* pNameDLL)
-------------------------
Если что не так, пишите и выкладывайте Ваш пример, будет разбираться.
Мой пример на луа см выше
   nikolz  , а первая которая просто через скрипт, я так понимаю работает по принципу как ffi? Я правда не смотрел реализации этой ffi.
нет это просто обертка второй
А ну да, точно. Это я что-то как-то бегло глянул. Конечно обёртка. Если ffi, там же прямо из скрипта нужная функция API вызывается, так вроде?
Как с помощью кода открыть график и отформатировать его по шаблону?, Как с помощью кода открыть график и отформатировать его по шаблону?
 
Ещё вот что. По Таблице обезличенных сделок как раз таки и неплохо брать данные в таком формате, как предлагается в этой функции. Там же как раз сделки все с биржи и время и цены. Я для себя правда ни разу эту таблицу не заказывал. У qpile свой подход. Он видимо так может работать чисто по времени в отличии от свечей как в Lua.
Как с помощью кода открыть график и отформатировать его по шаблону?, Как с помощью кода открыть график и отформатировать его по шаблону?
 
Цитата
nikolz написал:
Цитата
Alexander написал:
Если пользоваться функцией GET_CANDLE и 3-й параметр STRING parameter_name не устанавливать в - "", т.к. Таблица обезличенных сделок не заказывается у брокера, то что конкретно надо туда писать? В документации пишут брать параметр из  Таблицы текущих значений параметров. Их перечень см. Функции для получения значений Таблицы текущих торгов. Если мне нужно у свечи данные закрытия свечи, то какой параметр указать? Просто CLOSE такого нет там. Пробовал CLOSEPRICE - не то. И вообще причём здесь Таблица текущих торгов?
Причем здесь таблица обезличенных сделок?
Вы же свечу заказываете.
Ну как причём? Это же не я придумал. Это разработчики квика. У них так и написано в документации: "Значение «parameter_name» должно соответствовать одному из значений имени параметра из Таблицы текущих значений параметров. Их перечень см. Функции для получения значений Таблицы текущих торгов. Если «parameter_name» указан как «», то поиск осуществляется по данным Таблицы обезличенных сделок."
Ну это ещё ладно. С Таблицей обезличенных сделок как раз таки всё понятно. Я то спрашивал как раз про другое, когда не по таблице. Тогда что писать?
Как с помощью кода открыть график и отформатировать его по шаблону?, Как с помощью кода открыть график и отформатировать его по шаблону?
 
Что даже разработчики не могут ответить на такой простой вопрос? Я понимаю, что qpile уже не поддерживается, я и сам давно перешёл на lua, но всё же - раз в quik до сих пор qpile можно использовать, то по хорошему поддержке стоило бы дать ответ.
Выгрузка библиотек
 
Цитата
nikolz написал:
ссылка для скачивания  dll с функциями выгрузки
https://transfiles.ru/cp4bi

выгрузить на Lua5.3 :
require"nkDDD"
nkDDD.freeDLL( имяВыгружаемойDLL)

для выгрузки на СИ  функция
void nkfreeDLL(char* pNameDLL)
-------------------------
Если что не так, пишите и выкладывайте Ваш пример, будет разбираться.
Мой пример на луа см выше
nikolz, а первая которая просто через скрипт, я так понимаю работает по принципу как ffi? Я правда не смотрел реализации этой ffi.
Выгрузка библиотек
 
Ха-Ха-Ха. Всё!!! Ребята!!! Я долго ржал не мог поверить в увиденное. Но это так. Нашлась долгожданная причина невыгрузки. Имя файла dll было luacdllopt.dll, внутри функция через которую вызываются из скрипта функции dll - luaopen_luacdllopt, ну т.е. все вызовы я делал через переменную так:

luacdllopt = require("luacdllopt")
luacdllopt.имя функции

Так вот поменял имя проекта на luacdllopts и имя функции на luaopen_luacdllopts и всё заработало - всё без проблем выгружается и файл удаляется! Пробовал и другие разные имена - всё работает как надо!!!!!! Как только возвращаешь имена обратно на luacdllopt - так всё, никак файл не удаляется. Как такое получается и чей это косяк - толи самого квика, толи Lua тут не определишь, но точно чей то из них. Какая то функция некорректно обрабатывает имена видимо. И вот из-за такой мелочи потрачено столько времени, и грустно и смешно просто. Кто хочет можете у себя попробовать задать такие же имена как у меня были, посмотрите будет такой же негативный эффект или нет.
Как с помощью кода открыть график и отформатировать его по шаблону?, Как с помощью кода открыть график и отформатировать его по шаблону?
 
Если пользоваться функцией GET_CANDLE и 3-й параметр STRING parameter_name не устанавливать в - "", т.к. Таблица обезличенных сделок не заказывается у брокера, то что конкретно надо туда писать? В документации пишут брать параметр из  Таблицы текущих значений параметров. Их перечень см. Функции для получения значений Таблицы текущих торгов. Если мне нужно у свечи данные закрытия свечи, то какой параметр указать? Просто CLOSE такого нет там. Пробовал CLOSEPRICE - не то. И вообще причём здесь Таблица текущих торгов?
Выгрузка библиотек
 
Цитата
Станислав написал:
Настройте динамическое название библиотеки, например, mylib-723cf36f.dll, где 723cf36f - динамический хеш. Да, будут оставаться файлы старых версий и в памяти и на диске, но их можно подчищать после закрытия терминала.
Как это сделать? Можно поподробней.
Выгрузка библиотек
 
Цитата
Вадим Никитин написал:
Вот это тоже странно, если библиотека, которую вы приводили здесь не выгружается указанными способами, то что-то явно не так. Она же вообще не создаёт никаких ресурсов, значит FreeLibrary должен её освободить. Попробуйте через Process Explorer от Руссиновича посмотреть, какие процессы её используют. Вроде он показывает кем захвачен файл. Может и более простой есть способ, но я давно в Windows не копался.
Да тут далеко ходить не надо. Я выше писал и скрин выкладывал, что при попытке удалить файл .dll библиотеки если не через Total Commander, а через стандартный Проводник(explorer.exe), то вылазит сообщение, не как у Тотала - "снимите защиту от записи", а чётко и ясно, что файл ещё используется "Информационная система QUIK...". Так что тут сто процентов QUIK не даёт сам, ну или Lua.
Выгрузка библиотек
 
Цитата
Kalmar написал:
Цитата
Alexander написал:
 
Цитата
Kalmar  написал:
 
Цитата
 Alexander   написал:
Тут что-то другое, DLL выгружается, а файл почему-то не закрыт, я такие выводы делаю, хотя я сам этот файл вообще не трогаю, ну в смысле не открываю его.
  -На момент выгрузки все счётчики нулевые?
-Дебагер, в списке загруженных модулей показывает либу
 Загрузил квик. Загрузил скрипт. Он загружает DLL один раз в самом начале. Скрипт отработал. DLL осталась. Выгрузка принудительно показывает, что выгрузка - OK! Ошибок FreeLibrary не выдаёт. Но файл не удалить. Я даже простую DLL, фактически пустую загружаю и скрипт с одной функцией вызова из неё и то же самое. Здесь что-то странное вообще получается. Раньше помница вроде как всё же после скрипта DLL выгружалась сама. Что после произошло и происходит надо понять.
Ну так счетчики-то нулевые или нет?
В дебагере после выгрузки модуль виден или нет?
Kalmar, здесь я не совсем понял, что имелось ввиду про виден модуль или нет. Виден модуль в смысле каким образом? Есть у меня такой тест:

 PrintDbgStr("\nТаблица загруженных модулей package.loaded:")

 for k,v in pairs(package.loaded) do
   PrintDbgStr(string.format("%s=%s", k, tostring(v)))
 end

 PrintDbgStr("\nТаблица  сохранённых загрузчиков package.preload:")

 for k,v in pairs(package.preload) do
   PrintDbgStr(string.format("%s=%s", k, tostring(v)))
 end

 PrintDbgStr("\nТаблица  спользуемая require для контроля как загружать модули package.searchers:\n")

 for k,v in pairs(package.searchers) do
   PrintDbgStr(string.format("%s=%s", k, tostring(v)))
 end

PrintDbgStr("\nЗагружен модуль: " .. tostring(package.loaded["luacdllopt"]))
PrintDbgStr("\nЗагружен модуль: " .. tostring(package.loaded["string"].table))

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

00000001 11:56:48 [6636]
00000002 11:56:48 [6636] Таблица загруженных модулей package.loaded:
00000003 11:56:48 [6636] package=table: 00000260392A0560
00000004 11:56:48 [6636] bit=table: 0000026039408A40
00000005 11:56:48 [6636] math=table: 0000026039408A00
00000006 11:56:48 [6636] utf8=table: 0000026039408600
00000007 11:56:48 [6636] string=table: 00000260394085C0
00000008 11:56:48 [6636] _G=table: 00000260392A06E0
00000009 11:56:48 [6636] coroutine=table: 0000026039408680
00000010 11:56:48 [6636] table=table: 0000026039408900
00000011 11:56:48 [6636] debug=table: 0000026039408D00
00000012 11:56:48 [6636] io=table: 0000026039408B40
00000013 11:56:48 [6636] os=table: 0000026039408240
00000014 11:56:48 [6636]
00000015 11:56:48 [6636] Таблица  сохранённых загрузчиков package.preload:
00000016 11:56:48 [6636]
00000017 11:56:48 [6636] Таблица  спользуемая require для контроля как загружать модули package.searchers:
00000018 11:56:48 [6636] 1=function: 00000260392A05E0
00000019 11:56:48 [6636] 2=function: 00000260394088C0
00000020 11:56:48 [6636] 3=function: 0000026039408CC0
00000021 11:56:48 [6636] 4=function: 0000026039408700
00000022 11:56:48 [6636]
00000023 11:56:48 [6636] Загружен модуль: nil
00000024 11:56:48 [6636]
00000025 11:56:48 [6636] Загружен модуль: nil
00000026 11:56:48 [6636] A = table: 000002602C50AAD0
00000027 11:56:48 [6636] luacdllopt[DllMain][DLL_THREAD_DETACH]: thread with ID = 0x1570 is joining to DLL
00000028 11:56:48 [6636] luacdllopt[DllMain][DLL_THREAD_DETACH]: thread [ID = 0x1570] is detaching from DLL
00000029 12:02:08 [6636]
00000030 12:02:08 [6636] Таблица загруженных модулей package.loaded:
00000031 12:02:08 [6636] utf8=table: 0000026039408B00
00000032 12:02:08 [6636] bit=table: 0000026039408BC0
00000033 12:02:08 [6636] string=table: 0000026039408A40
00000034 12:02:08 [6636] table=table: 0000026039408F40
00000035 12:02:08 [6636] package=table: 0000026039408D00
00000036 12:02:08 [6636] _G=table: 0000026039408240
00000037 12:02:08 [6636] debug=table: 0000026039408B40
00000038 12:02:08 [6636] coroutine=table: 00000260394082C0
00000039 12:02:08 [6636] math=table: 0000026039408A80
00000040 12:02:08 [6636] io=table: 00000260394086C0
00000041 12:02:08 [6636] os=table: 0000026039408B80
00000042 12:02:08 [6636]
00000043 12:02:08 [6636] Таблица  сохранённых загрузчиков package.preload:
00000044 12:02:08 [6636]
00000045 12:02:08 [6636] Таблица  спользуемая require для контроля как загружать модули package.searchers:
00000046 12:02:08 [6636] 1=function: 0000026039408580
00000047 12:02:08 [6636] 2=function: 0000026039408600
00000048 12:02:08 [6636] 3=function: 0000026039408540
00000049 12:02:08 [6636] 4=function: 0000026039408940
00000050 12:02:08 [6636]
00000051 12:02:08 [6636] Загружен модуль: nil
00000052 12:02:08 [6636]
00000053 12:02:08 [6636] Загружен модуль: nil
00000054 12:02:08 [6636] A = table: 000002602C50AA50
00000055 12:02:08 [6636] luacdllopt[DllMain][DLL_THREAD_DETACH]: thread with ID = 0x2A74 is joining to DLL
00000056 12:02:08 [6636] luacdllopt[DllMain][DLL_THREAD_DETACH]: thread [ID = 0x2A74] is detaching from DLL

Так что, как можно заметить мой модуль не показывает вообще. Как его увидеть в загруженных не знаю. Это если через Lua.
Выгрузка библиотек
 
Цитата
Alexander написал:
Цитата
Вадим Никитин написал:
nikolz , поддерживаю, очень хорошая книга.

Alexander , а какой версии вы используете QUIK и Lua к нему?
10.0.1.18
Lua 5.3.5
Выгрузка библиотек
 
Цитата
Kalmar написал:
Цитата
Alexander написал:
Тут что-то другое, DLL выгружается, а файл почему-то не закрыт, я такие выводы делаю, хотя я сам этот файл вообще не трогаю, ну в смысле не открываю его.
-На момент выгрузки все счётчики нулевые?
-Дебагер, в списке загруженных модулей показывает либу
Загрузил квик. Загрузил скрипт. Он загружает DLL один раз в самом начале. Скрипт отработал. DLL осталась. Выгрузка принудительно показывает, что выгрузка - OK! Ошибок FreeLibrary не выдаёт. Но файл не удалить. Я даже простую DLL, фактически пустую загружаю и скрипт с одной функцией вызова из неё и то же самое. Здесь что-то странное вообще получается. Раньше помница вроде как всё же после скрипта DLL выгружалась сама. Что после произошло и происходит надо понять.
Выгрузка библиотек
 
Цитата
Вадим Никитин написал:
nikolz, поддерживаю, очень хорошая книга.

Alexander, а какой версии вы используете QUIK и Lua к нему?
10.0.1.18
Выгрузка библиотек
 
Цитата
Вадим Никитин написал:
ействительно ли перезапуск Квика так сложен, что стоит тратить на этот костыль столько времени? Тем более, что это будет крайне ненадёжное решение. Ведь по сути делается то, что не предусмотрено по дизайну, а это всегда ведёт к Undefined Behaviour. В итоге можно потратить ещё больше времени на отладку костыля, вместо того, чтобы разрабатывать торговую стратегию.
Перезапуск как таковой не сложен. А вот время он занимает прилично, и это утомляет. Когда увидел косяк, надо быстро исправить код DLL, скомпилять(это быстро) и потом перезаписать двоичный файл. Вот и ждёшь пока он заново загрузится. При загрузке даже не логинюсь для тестов(ну когда без этого можно обойтись), а то ещё дольше будшь ждать. Вообще вся эта процедура загрузки квика долгая, причём ещё надо ввсести логин, пароль, потом я запускаю дебагер для OutputDebugString, а в нём ещё фильтр настроить по номеру процесса. Саму процедуру эту я уже упростил как мог, потому как мне это жутко надоело каждый раз всё это проделывать в описанной последовательности. Я написал прогу на С, которая запускает квик, ждёт появления окна логина/пароля, вводит туда эти данные, нажимает OK, находит сам квик и его PID, запускает дебагер, ищет его окно и вводит туда этот PID и жмёт OK, потм ждёт окна если появится в квике где надо ответить НЕТ на замену инструментов. И после этого остаётся только дождаться когла сам квик загрузится. По сути я только запускаю прогу один раз через ярлык и всё, остальные действия все нужные делает программа. Если бы я ещё и это всё вручную делал, то это вообще кошмар был бы.
Выгрузка библиотек
 
Цитата
Вадим Никитин написал:
Да, есть.GetModuleHandle
Ну да точно. Я свои ранние варианты посмотрел, так оказывается я использовал уже эту функцию, правда не в целях выгрузки, потом закомментировал и забыл, ну а потом затупил что-то совсем, что и не вспомнил.)))
Выгрузка библиотек
 
Цитата
Kalmar написал:
Цитата
Alexander написал:
FreeLibrary ошибок не выдаёт, скрипт заканчивается, более DLL никто не использует, все ресурсы освобождены, но вот файл библиотеки я удалить так и не могу. Что в обёртке, что в самовыгрузке, - тоже писал ранее - результат один и тот же. Выгрузка без ошибок, файл не удаляется.
Ну значит что-то идет не так. Чудес же не бывает. ))

Можно попробовать подебажить ситуацию так: завести две глобальных переменных g_procs, g_threads, и
- на каждый DLL_PROCESS_ATTACH делать g_procs++
- на каждый  DLL_PROCESS_DETACH делать g_procs--
- на каждый   DLL_THREAD_ATTACH делать  g_threads++
- на каждый   DLL_THREAD_DETACH делать  g_threads--и потом посмотреть статистику.
У меня debug есть, весь идёт не только по количеству, но и по всем идентификаторам. Все мои потоки успешно все завершены, да идут время от времени вызовы подключений и отключений других не моих потоков, может квика, может Lua, не знаю, но они сто процентов мою DLL не загружают же через LoadLibrary, так как они вообще не знают что такая есть, это просто так ОС работает, для всех потоков код прогоняет перед их запуском из DLL в их контексте. Я даже 1 поток загружаю или выгружаю, а не, даже вообще не запускаю потоков ни одного и всё равно результат - файл не удалить. Тут что-то другое, DLL выгружается, а файл почему-то не закрыт, я такие выводы делаю, хотя я сам этот файл вообще не трогаю, ну в смысле не открываю его.
Выгрузка библиотек
 
Цитата
nikolz написал:
Удачная компиляция dll, хотя тест запущен как и во втором случае, но после вызова Вашей функции вызвана моя функция выгрузки dll.
А хэндл для выгрузки DLL, которая выгружает основную, она как по имени получает?
Выгрузка библиотек
 
Цитата
Вадим Никитин написал:
Безусловно, можно выгрузить библиотеку и принудительно. Для этого можно найти HANDLE библиотеки по её имени, что-то вроде GetModuleHandle и вызвать FreeLibrary с ним.
Есть такая функция, которая по имени выдаёт хэндл для библиотеки?
Выгрузка библиотек
 
Цитата
Вадим Никитин написал:
Как уже упомянуто, библиотека в адресном пространстве процесса присутствует в единственном экземпляре. То есть, если несколько скриптов используют одну библиотеку и запускаются из одного процесса QUIK, то все они будут использовать одну и ту же копию библиотеки.
Ну я с этим полностью согласен и знаю это.
Цитата
Вадим Никитин написал:
Для того, чтобы выгрузить библиотеку, процесс, в адресном пространстве, которого она находится, должен вызвать FreeLibrary ровно столько раз, сколько раз она была загружена, уменьшая счётчик ссылок. Когда счётчик ссылок обнулится, то ОС выгрузит библиотеку и освободит файл.
Здесь мне кажется не совсем верно написали. В адресное пространство процесса отображается DLL, когда он её загружает через LoadLibrary например. Он её может и выгрузить через FreeLibrary, но это не значит, что ОС выгрузит её, так как другие процессы могли так же загружать её. И ОС ведёт этот счётчик сколько раз её загружали через LoadLibrary разные процессы. И когда последний процесс вызовет FreeLibrary, тогда и счётчик ОС для этой библиотеки обнулится и ОС выгрузит её опять же когда сочтёт нужным. Наверное это имелось в виду. Или что, разные потоки одного процесса могут вызывать каждый LoadLibrary, и потом каждый из них должен вызывать FreeLibrary? Или если в цикле например в одном потоке вызвать несколько раз LoadLibrary, то мне потом надо столько же раз вызвать и FleeLibrary для успешной выгрузки? Пример с общей глобальной переменой понимаю, вернее знаю про это.
Выгрузка библиотек
 
Цитата
nikolz написал:
Цитата
Alexander написал:
 
Цитата
nikolz  написал:
Я Вроде вам написал, что сделать. Вы сделали? Какой результат?Если не выгрузилась, то скажу что делать дальше.
 Что ещё попробовать?
В свободное время протестирую Вашу dll (приведенную Выше) и напишу Вам результат.
------------------------
Могу выложить готовую dll для выгрузки вашей библиотеки .
Да, если можно, скиньте. Посмотрю, может что прояснит для меня. На любое облако для прямого скачивания типа яндекса или майлру, а ссылку здесь можно или в ЛС.
Выгрузка библиотек
 
Цитата
Kalmar написал:
Цитата
Alexander написал:
extern "C" LUALIB_API int luaopen_luacdllopt(lua_State *L) {
#if LUA_VERSION_NUM >= 502 luaL_newlib(L, ls_lib);
#else luaL_openlib(L, "luacdll", ls_lib, 0);#endif return 1;
}
я так понимаю, что это код внутри твоей либы, ты объявляешь функцию и ее просовываешь в луа, верно?
чтобы иметь возможность делать так:
Цитата
Alexander написал:
luacdllopt = require("luacdllopt")

Сразу хочу уточнить для понимания: я же правильно понимаю, что возможность загрузить-выгрузить нужна для быстрой отладки, чтобы не рестартить квичок? типа загрузил-попробовал-выгрузил-пересобрал-загрузил-попробовал и т.д.?

Если да, то мне кажется есть путь проще: нужно сделать dll-обертку, для работы с твоей целевой dll-кой, которая может делать LoadLibrary/FreeLibrary, и после загрузки твоей либы она биндит адреса функций в тестовой dll, на какие-то луа-методы.

Все  вызовы lua_mycallN находятся в обертке, но реально делают вызов из целевой либы.Я могу ошибаться в деталях, и имена вызовов условны, для понимания что к чему.

При этом работа происходит примерно так:
1. загружаем luamywrap.dll, она содержит какое-то кол-во целевых вызовов, ну, для которых ты все это затеял, и две специальных процедуры:
lua_LoadMyLib(name) -- она делает LoadLibrary, сохраняет ее хендл где-то у себя и биндит реальные адреса процедур MyCallN в функции-обертки lua_mycallN.
lua_UnLoadMyLib(name) -- она делает FreeLibrary для хендла полученного при загрузке либы, и сбрасывает указатели в lua_mycallN, чтобы небыло падежей в случае случайного вызова.
2. делаем вызов lua_LoadMyLib(myDLLName).
3. теперь можно работать вызывая из луа lua_mycallN  - они будут работать как надо.
4. когда закончили - вызываем lua_UnLoadMyLib(), целевая dll выгружается и можно с ней что-то делать.
5. ????
6. profit!
Всё верно по поводу вопроса в самом начале сообщения. Всё, что Вы описали я уже проделал в разных вариантах и именно в варианте как у вас тоже, ранее об этом писал здесь: https://forum.quik.ru/messages/forum10/message69406/topic4425/#message69406 Всё дело в том, что выгрузка то происходит без ошибок, т.к. FreeLibrary ошибок не выдаёт, скрипт заканчивается, более DLL никто не использует, все ресурсы освобождены, но вот файл библиотеки я удалить так и не могу. Что в обёртке, что в самовыгрузке, - тоже писал ранее - результат один и тот же. Выгрузка без ошибок, файл не удаляется. За совет конечно спасибо.
Нужно создать робота на QPILE. ( за оплату ), Кто сможет сделать робота сканер по RSI ?
 
Так нужна только таблица, чтобы визуально наблюдать? Или нужен именно робот, чтобы ещё и сам покупал - продавал? Или купил-продал вручную?
Выгрузка библиотек
 
Цитата
nikolz написал:
Я Вроде вам написал, что сделать. Вы сделали? Какой результат?Если не выгрузилась, то скажу что делать дальше.
Что ещё попробовать?
Выгрузка библиотек
 
Цитата
Alexander написал:
[img]data:image/png;base64,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[/img]
Картинка из буфера почему-то не вставилась. Хотя когда писал и вставил, то картинка нормально отобразилась в окне где пишу.
Выгрузка библиотек
 
[img]data:image/png;base64,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[/img]
Выгрузка библиотек
 
nikolz, выяснилось ещё вот что - оказывается даже потоки мои здесь вообще не причём и всякие там выделения ресурсов тоже ни причём. Вот код простейший DLL:

#include <windows.h>
#define LUA_LIB
#define LUA_BUILD_AS_DLL
#include "lua.hpp"

//==========================================================­============================================================­=================
BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved)
{
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
OutputDebugString((LPCWSTR)L"Disable DLL");
break;
}
return TRUE;
}
//==========================================================­============================================================­=================
static int forLua_GetCurrentThreadId(lua_State *L) {
OutputDebugString(L"luacdllopt[forLua_GetCurrentThreadId]: GetCurrentThreadId() function is called...");
lua_pushinteger(L, GetCurrentThreadId());
return(1);
}
//==========================================================­============================================================­=================
static struct luaL_Reg ls_lib[] = {
{ "GetCurrentThreadId", forLua_GetCurrentThreadId },
{ nullptr, nullptr }
};
//==========================================================­============================================================­=================
extern "C" LUALIB_API int luaopen_luacdllopt(lua_State *L) {
#if LUA_VERSION_NUM >= 502
luaL_newlib(L, ls_lib);
#else
luaL_openlib(L, "luacdll", ls_lib, 0);
#endif
return 1;
}

В скрипте вызываю:

package.cpath =  package.cpath .. ";" .. getWorkingFolder() .. "\\lib5" .. _VERSION:sub(_VERSION:len()) .. "\\?.dll"
luacdllopt = require("luacdllopt")

PrintDbgStr("1) GetCurrentThreadId() = " .. tostring(luacdllopt.GetCurrentThreadId()))

Уж куда ещё проще то. И после пробую удалить файл библиотеки - не удаляется! И ещё всё время удалять пробовал через Total Commander. А он типа не могу и всё - снимите защиту от записи. А тут попробовал удалить Проводником и выдал он мне следующее:



Так что то это? Квик значит виноват? Он не даёт удалить потому, что держит файл открытым.
Выгрузка библиотек
 
Наверное есть счётчик потоков подключённых и его надо как-то сбросить.
Выгрузка библиотек
 
nikolz, попробовал вставил вызов DisableThreadLibraryCalls после case DLL_PROCESS_ATTACH: как Вы писали - результат отрицательный. Потоки перестали подключаться и отключаться к моей DLL, ну вернее перестали приходить сообщения из DLL_THREAD_ATTACH и DLL_THREAD_DETACH, что я оттуда делал в debug, ну и деактивировался мой код в  DLL_THREAD_DETACH, который закрывал дескрипторы завершённых потоков. Файл библиотеки удалить не могу.
Выгрузка библиотек
 
Цитата
nikolz написал:
Alexander ,
У меня все это работает.
Но если Вы будете сами выдумавать а не делать ровно то что я написал, то не вижу смысла Вам помогать.
Хорошо, сейчас попробую в точности. Может я не правильно понял как эта функция работает.
Выгрузка библиотек
 
Я сейчас попробую сделать вызов DisableThreadLibraryCalls не в в функции  WINAPI DllMain(HINSTANCE hinstDLL ...
после
         case DLL_PROCESS_ATTACH:
как Вы писали, а в другом месте - в вызове функции, которая закрывает все работающие потоки если таковые есть.
Выгрузка библиотек
 
nikolz, что ещё можно?
Выгрузка библиотек
 
Цитата
nikolz написал:
Цитата
Alexander написал:
Такой прокси вызов функций из основной DLL, как описал выше так же можно организовать и по другому, т.е. не возвращая адрес нужной функции в скрипт с последующим вызовом функции через переменную, получившую адрес этой функции. А можно вызывать функции как обычно через имя модуля.имя функции, но эти функции надо сделать прокси-функциями, т.е они должны принимать все нужные параметры для вызова, а потом через переменную указатель вызывать нужную функцию из основной DLL, передавая ей эти параметры обычной функции C. Но это просто к слову. Так не стал, хотя разницы нет. Всё равно же результат никакой.
Я Вроде вам написал, что сделать. Вы сделали? Какой результат?
Если не выгрузилась, то скажу что делать дальше.
Рад бы вобщем такое попробовать, но не могу, мне нужен DLL_THREAD_DETACH. Ещё есть подозрение, что вызов DisableThreadLibraryCalls cделает так, что DLL_THREAD_ATTACH и DLL_THREAD_DETACH просто не будут приходить в DLL, но сами потоки будут и присоединяться и отсоединяться, просто уведомлений не будет.
Выгрузка библиотек
 
Кстати, а есть ли такая функция, которая бы запрещала бы вообще присоединяться к моей библиотеке другим потокам? А то кроме потоков, которые я сам запускаю к ней присоединяются все кому не поподя - какие-то потоки квика или луа, которые мне не нужны. Это было бы полезно для меня, хотя проблему не решает, просто чужие потоки забивают мне отладочный вывод. Можно конечно каждый раз сравнивать свой-чужой, но это лишний код.
Выгрузка библиотек
 
Цитата
nikolz написал:
попробуйте в dll ,которую надо выгрузить
в функции  WINAPI DllMain(HINSTANCE hinstDLL ...
после
          case DLL_PROCESS_ATTACH:
вставить
DisableThreadLibraryCalls(hinstDLL);G
Посмотрел, что это за функция. Это мне не пойдёт, т.к. у меня в DLL_THREAD_DETACH происходит удаление дескрипторов потоков из массива потоков, которые закрылись. Если сделаю её вызов, то DLL_THREAD_DETACH мне поступать не будут.
Страницы: Пред. 1 2 3 4 5 6 След.
Наверх