Потребовался cURL в скриптах lua для Quik. Использую для этого Lua-cURLv3. Но уже несколько недель не могу добиться того, чтобы cURL заработал в Quik.
Сначала скомпилировал cURL с OpenSSL и zlib, получив все необходимые dll-библиотеки (libcurl.dll, libcrypto-3-x64.dll, libssl-3-x64.dll, zlibwapi.dll). Затем с помощью LuaRocks скомпилировал модуль Lua-cURLv3 (получил lcurl.dll и необходимые к нему lua-файлы для скрипта). Все скомпилировалось без ошибок. Проверил с помощью специальной программы Dependencies (с Github), что все зависимости в lcurl.dll подключены. Добавил пути к этим либам в Path - Quik их видит, нормально без ошибок подключает Lua-cURLv3 скриптом:
Скрытый текст
Код
package.cpath = ";;C:\\Open_Broker_QUIK\\clibs\\?.dll;"
package.path = ";;C:\\Open_Broker_QUIK\\?.lua;"
local curl = require "cURL"
local cl = curl.easy_init()
Но, если попробовать получить какие-то данные следующим скриптом, то QUIK Junior 9.1.3 выбрасывает неизвестное исключение "unrecognized exception", а QUIK Junior 11 и Open_Broker_QUIK 10.2.3.7 падают при запуске скрипта:
Скрытый текст
Код
package.cpath = ";;C:\\Open_Broker_QUIK\\clibs\\?.dll;"
package.path = ";;C:\\Open_Broker_QUIK\\?.lua;"
local curl = require "cURL"
local cl = curl.easy_init()
function main()
cl:setopt_url("https://jsonplaceholder.typicode.com/posts/1")
cl:setopt(curl.OPT_SSL_VERIFYPEER, false)
cl:setopt_writefunction(function (res)
PrintDbgStr(res)
end)
cl:perform()
message(tostring(cl:getinfo(curl.INFO_RESPONSE_CODE)))
cl:close()
end
Примечательно, что если закомментировать функцию cl:setopt_writefunction, то message(tostring(cl:getinfo(curl.INFO_RESPONSE_CODE))) вернет код ответа 200, т.е. запрос был выполнен успешно. Однако способа, как получить тело ответа без cl:setopt_writefunction я не нашел. Может вы знаете?
При этом Lua-cURLv3 нормально работает в обычном интерпретаторе lua. Если запустить следующий скрипт через cmd (C:\lua-scripts>lua test.lua), нужный результат будет выведен в консоль:
Скрытый текст
Код
package.cpath = ";;C:\\Open_Broker_QUIK\\clibs\\?.dll;"
package.path = ";;C:\\Open_Broker_QUIK\\?.lua;"
local curl = require "cURL"
local cl = curl.easy_init()
function main()
cl:setopt_url("https://jsonplaceholder.typicode.com/posts/1")
cl:setopt(curl.OPT_SSL_VERIFYPEER, false)
cl:setopt_writefunction(function (res)
print(res)
end)
cl:perform()
print(tostring(cl:getinfo(curl.INFO_RESPONSE_CODE)))
cl:close()
end
main()
В всех Quik'ах использую версию lua 5.4.1. На компьютере установлен lua 5.4.2 (он же используется в LuaRocks). Для теста использую версии Quik: QUIK-Junior 9.1.3, QUIK-Junior 11, Open_Broker_QUIK 10.2.3.7. Дамп падения QUIK-Junior 9.1.3 (он тоже, как и другие падет, если в скрипте убрать функцию main()) можно скачать здесь: первый и второй (почему-то создаются сразу два).
Скачать скомпилированные под x64 либы можно здесь. Папки clib и cURL и файл cURL.lua необходимо разархивировать в корень папки QUIK. Добавить папку квика и папку clib в Path и перезапустить Quik.
Прошу помощи! У меня не осталось предположений, в чем может быть проблема. Может я делаю что-то не так? Или дело в Quik? У кого есть опыт и знания поделитесь, пожалуйста.
P.S. У меня осталось только 1 предположение, что нужно было как-то использовать библиотеку lua54.dll из папки с QUIK. Но во время создания либы Lua-cURLv3 я ни разу не столкнулся с тем, чтобы она была где-то нужна.
funduk написал: Всё, что в luarocks компилится для квика, должно линковаться с квиковской же lua54.dll
Благодарю за ответ. Объясните, пожалуйста, подробнее, что нужно сделать. Я скомпилировал с помощью luarocks файл lcurl.dll (Lua-cURLv3). У него в зависимости указан сам cURL (libcurl.dll):
Как и в какой момент нужно добавлять в зависимость квиковскую lua54.dll?
funduk написал: Всё, что в luarocks компилится для квика, должно линковаться с квиковской же lua54.dll
Я бы не сказал, что все. По крайней мере, когда я собирал аналогичный комплект под lua 5.1, то все это делалось под чистым lua и работало в терминале без проблем.
funduk написал: Всё, что в luarocks компилится для квика, должно линковаться с квиковской же lua54.dll
Я бы не сказал, что все. По крайней мере, когда я собирал аналогичный комплект под lua 5.1, то все это делалось под чистым lua и работало в терминале без проблем.
Я бы попробовал использовать квиковскую dll, но не понимаю куда ее подключать? На каком этапе?
nikolz написал: Зачем его с чем-то собирать, а не использовать для вызова os.execute()
Может, как костыль, сойдет. Но:
Скрытый текст
Как получить ответ из функции os.execute в переменные?
Как сделать, чтобы окошко командной строки не мигало при вызове os.execute?
Эффективно ли будет работать скрипт, если вызывать множество запросов за короткий период?
Из Википедии. cURL — программа командной строки. Libcurl — это библиотека API для передачи, которую разработчики могут встроить в свои программы; cURL действует как автономная обёртка для библиотеки libcurl.
Уважаемая служба поддержки! Пожалуйста, обратите внимание на мой вопрос. Я выложил скомпилированные библиотеки, которые работают на чистом lua, но не работают в QUIK, выложил дампы падения QUIK (раз, два). Проанализируйте, пожалуйста, хотя бы дампы, скажите в чем может быть дело?
Также объясните, пожалуйста, кто-нибудь куда присобачивать квиковскую lua54.dll, при компиляции в luarocks? Lua-cURLv3 в luarocks компилирую такой командой:
Сергей написал: Однако способа, как получить тело ответа без cl:setopt_writefunction я не нашел. Может вы знаете?
в коде есть такое для Multi:
Код
-- reset callbacks to all easy handles
local function reset_easy(self)
if not self._easy_mark then -- that means we have some new easy handles
for h, e in pairs(self._easy) do if h ~= 'n' then
e:setopt_writefunction (function(str) buffers:append(e, "data", str) end)
e:setopt_headerfunction(function(str) buffers:append(e, "header", str) end)
то есть вроде бы там всё есть для принятия данных в lua таблицы и для Easy.
Цитата
ExpE написал: Объясните, пожалуйста, подробнее, что нужно сделать. Я скомпилировал с помощью luarocks файл lcurl.dll (Lua-cURLv3).
В папке с luarocks где-то есть lua54.dll и lua54.lib, или есть config*.lua, который содержит нужные пути, что-то типа такого:
Нужно заменить include файлы на правильную версию (если ещё не сделано), заменить lua54.dll из lib папки на квиковский, и lua54.lib из lib папки на аналогичный, полученный из квиковской lua54.dll по инструкции в интернете на тему create lib from dll, например этой, и перекомпилить, динамически подключая lua54.dll (а не статически, как сейчас). После чего lcurl.dll по идее станет совместим с квиком (но, видимо, перестанет быть совместимым с обычным интерпретатором).
Отличия lua5*.dll среди прочего в том, что есть код синхронизации, lua_lock и lua_unlock, вместо пустой заглушки в стандартном интерпретаторе.
Поможет ли это - хз :) для проверки попытайтесь не пользоваться квиковскими функциями внутри колбэка, передаваемого в setopt_writefunction. Создайте файл встроенными средствами lua и печатайте туда. Если сработает, то дело может быть в недоступности PrintDbgStr внутри lcurl.dll, и вероятность решения проблемы от процедуры выше повысится.
funduk, Спасибо вам огромное за кучу полезной информации! Обязательно попробую все сделать и напишу о результатах. Если получится, выложу сюда работающие либы.
ExpE написал: [QUOTE]nikolz написал: Зачем его с чем-то собирать, а не использовать для вызова os.execute()
Эффективно ли будет работать скрипт, если вызывать множество запросов за короткий период?
Код
[/CODE][/QUOTE]
Как получить ответ из функции os.execute в переменные?
Как сделать, чтобы окошко командной строки не мигало при вызове os.execute?
-------------------
вариант решения (не мигает, получаем ответ функции в переменные):[CODE]local Log=io.open("D:/x.txt","r"); io.input(Log)
os.execute("curl --version > D:/x.txt")--insecure --ssl-reqd smtps://e.mail.ru –-mail-from kamnik@mail.ru –-mail-rcpt receiver@company.com --user kamnik@mail.ru --upload-file D:/msg.txt")
--печать результата исполенения команды
print(io.read())
print(io.read())
print(io.read())
swerg написал: Для сборки вам не нужны никакие dllНужны .h файлы и .lib файлы, соответствующей используемой вами версии Lua (и версии, и платформы x86 или x64).Можно взять готовые файлы для сборки.Например здесь: https://github.com/swerg/simple-lua-c-dll/tree/master/contrib
Громаднейшее спасибо! Я заменил свою lua54.lib на вашу lua54.lib в папке с lua, который используется в luarocks, перекомпилировал Lua-cURL и все заработало! Я уже не надеялся)
Также больше спасибо за советы funduk и nikolz.
Готовый работающий Lua-cURLv3 можно скачать по этой ссылке. Скомпилировано под версию lua 5.4, поэтому в Квике в настройках нужно выбрать версию lua-5.4. Папки clibs, cURL и файл cURL.lua необходимо разархивировать в корень папки QUIK. Добавить папку Квика и папку clibs в Path и перезапустить Quik.
Пример кода, как использовать Lua-cURLv3:
Код
package.cpath = ";;C:\\Open_Broker_QUIK\\clibs\\?.dll;"
package.path = ";;C:\\Open_Broker_QUIK\\?.lua;"
local curl = require "cURL"
local cl = curl.easy_init()
function main()
cl:setopt_url("https://jsonplaceholder.typicode.com/posts/1")
cl:setopt(curl.OPT_SSL_VERIFYPEER, false)
cl:setopt_writefunction(function (res)
message(tostring(res))
end)
local res = cl:perform()
--message(tostring(cl:getinfo(curl.INFO_RESPONSE_CODE))) --код ответа
cl:close()
end
ExpE написал: Добавить папку Квика и папку clibs в Path и перезапустить Quik.
В системный PATH? Не до конца понял тут.
Пытаюсь использовать вашу либу, пока ошибка "error loading module 'lcurl' from file 'D:\VIA\dev\luacurl\clibs\lcurl.dll': The specified module could not be found."
Т.е. проблема пока с path как я понимаю... Подскажите пожалуйста.
вам надо написать путь туда, где вы положили эту библиотеку можно сделать так
Код
path = "C:/clibs/" -- здесь лежит dll
package.cpath = package.cpath .. path .. "?.dll"
Это понятно. Скрипт то видит lcurl.dll. Если его удалить или переименовать, то ошибка будет совсем другая. Моя ошибка говорит о том, что проблема, вероятнее всего, с зависимости внутри это dll и не находится ещё какой-то файл нужный.
Вот, для иллюстрации. Если я удаляю lcurl.dll то ошибка вот такая становится:
module 'lcurl' not found: no field package.preload['lcurl'] no file '' no file '' no file 'D:\VIA\QUIK_ROSB_osm\lcurl.lua' no file '' no file '' no file '' no file 'D:\VIA\QUIK_ROSB_osm\clibs\lcurl.dll' no file ''
Т.е. модуль lcurl.dll находится там, где надо. Проблема внутри него.