1 (2022-01-26 12:03:17 отредактировано swerg)

Тема: Где расположить dll-библиотеку для Lua5.3 и Lua5.4 в QUIK 8.11 ?

Я всегда был сторонником того, чтобы dll-файлы с внешними библиотеками для Lua следует помещать непосредственно в каталог с терминалом QUIK (т.е. в ту же папку, где info.exe). По-моему, это самый простой и надёжный путь, позволяющий не заморачиваться с настройкой путей к скриптам, при этом всё всегда надежно работает.

Но тут в QUIK 8.11 наступили неожиданные времена: одновременно нам доступна Lua 5.3 и Lua 5.4. Т.е. можно одновременно запускать разные скрипты, использующие внешние библиотеки, под разными версиями Lua. Сами dll-библиотеки, собранные для разных версий Lua, при этом не совместимы, это два разных файла но с одним названием.

Я теперь делаю так.
В каталоге с QUIK создал 2 папки:

  • \lib53 - для скриптов, собранных под Lua 5.3

  • \lib54 - для скриптов, собранных под Lua 5.4

Первой строчкой скрипта пишу:

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

Тогда скрипт сам настраивается на нужный путь к библиотекам в зависимости от версии Lua, в которой запущен скрипт, так что дальше делаем обычное require и все работает:

w32 = require("w32")

Есть идеи как это сделать лучше?

PS
Изготовление универсальных сборок библиотек, умеющих волшебно определять и подстраиваться под версию Lua, в этой теме предлагаю не обсуждать, это таки отдельное довольно хлипкое шаманство, которое [url=https://forum.quik.ru/forum10/topic6053/?PAGEN_1=2]хорошо обсуждалось на форуме QUIK[/url]. Основана беда с таким подходом - чтобы заработало надо существенно перерабатывать код библиотеки. Не всегда это возможно и рационально. На мой взгляд сделать две сборки библиотеки для разных версий Lua - проще и надежнее. В том числе с точки зрения переноса нового функционала.

Еще интересное:

  • [url=viewtopic.php?id=293]Список полезных библиотек для Lua[/url]

2

Re: Где расположить dll-библиотеку для Lua5.3 и Lua5.4 в QUIK 8.11 ?

swerg пишет:

Есть идеи как это сделать лучше?

Как вариант разные названия библиотек под разные версии lua
например: w32_51.dll w32_53.dll w32_54.dll

и подключать банально проверяя версию
if(_VERSION=="Lua 5.3")then w32 = require("w32_53") end
if(_VERSION=="Lua 5.4")then w32 = require("w32_54") end

3

Re: Где расположить dll-библиотеку для Lua5.3 и Lua5.4 в QUIK 8.11 ?

Просто так переименовать файлы библиотек нельзя. Имя библиотеки завязано на название стартовой экспортируемой из DLL функции. Соответственно при изменении названия файла библиотеки необходимо менять и имя стартовой функции. Это можно сделать, конечно, но тогда код библиотеки будет ещё в одном месте отличаться от оригинала, что не здорово, по-моему.

4 (2022-02-11 16:09:39 отредактировано kalikazandr)

Re: Где расположить dll-библиотеку для Lua5.3 и Lua5.4 в QUIK 8.11 ?

структура
C:/BotQuik
C:/BotQuik/lib
C:/BotQuik/lib/lua --lua lib
--сюда кладем w32 нужных версий (обязательно пробел между Lua и 5.х)
C:/BotQuik/lib/Lua 5.3 --dll
C:/BotQuik/lib/Lua 5.4

В корневой каталог квика кидаем вот этот модуль:

--parse_directory.lua
local parse = {}
function parse.parse(dir)
    local c, a, fn = 1
    while true do
        a, _ = string.find(dir, [[\]], c)
        if not a then
            fn = string.sub(dir, c)
            a, _ = string.find(fn, "%.")
            fn = fn:sub(1, a-1)
            parse[#parse+1] = fn
            break
        end
        parse[#parse+1] = string.sub(dir, c, a-1)
        c = a + 1
    end
end

return parse

в C:/BotQuik кидаем вот этот модуль:

--version.lua
local path = "C:/BotQuik/"
local V = _VERSION

package.path=package.path..";"..path.."?.lua"
package.path=package.path..";"..path.."lib/lua/?.lua"
package.cpath=package.cpath..";"..path.."lib/"..V.."/?.dll"

...и вот этого бота, либо создать под него отдельную папку в каталоге.

--test_V.lua
local w32
local exitflag
function OnInit(path)
    local pd = require'parse_directory'
    pd.parse(path) --получить массив папок
    __rootdir = pd[1].."\\"..pd[2]
    __script_path = table.concat(pd,"\\")
    __botname = table.remove(pd, #pd)
    ---[[
    message("OnInit\n"..
        "rootdir: "..tostring(__rootdir).."\n"..
        "script_path: "..tostring(__script_path).."\n"..
        "botname: "..tostring(__botname), 2
    )
    --]]
    dofile(__rootdir.."\\version.lua") --прописываем пути к папкам в зависимости от версии Lua
end

function main()
    w32 = require'w32'
    message("hWndQUIK= "..w32.FindWindowEx(0, 0, "InfoClass", ""))
    while not exitflag do sleep(1) end
end
function OnStop()
    exitflag = true
end

есть 2 варианта запуска скрипта test_V.lua (и других соответственно)
1. просто добавить в Доступные скрипты "C:/BotQuik/test_V.lua"
2. чуть сложнее, но гибче, если используется несколько терминалов:
2.1 Создаем в корневом каталоге квик папку scripts, "C:/QUIK/scripts"
2.2 в папке scripts создаем папку(и) с кодом(ми) клиента "C:/QUIK/scripts/2626**"
2.3 добавляем в папку с скодом клиента такого бота с тем же именем "C:/QUIK/scripts/2626**/test_V.lua":

--test_V.lua
dofile("C:/BotQuik/test_V.lua")

2.4 добавить в Доступные скрипты "C:/QUIK/scripts/2626**/test_V.lua" и запустить.
2.5 теперь в OnInit при парсинге пути к файлу доступен код клиента
2.6 если в терминале несколько клиентов или несколько терминалов, то поправив один раз код в "C:/BotQuik/test_V.lua", исправления будут доступны всем клиентам.

5 (2022-02-11 16:25:11 отредактировано kalikazandr)

Re: Где расположить dll-библиотеку для Lua5.3 и Lua5.4 в QUIK 8.11 ?

ах, да! кириллицу в названиях папок НЕ использовать!  если есть вариант лучше, чем я (в силу своего скудоумия) придумал для парсинга пути к файлу(parse_directory.lua), поделитесь пожалуйста.

6

Re: Где расположить dll-библиотеку для Lua5.3 и Lua5.4 в QUIK 8.11 ?

swerg пишет:

Просто так переименовать файлы библиотек нельзя. Имя библиотеки завязано на название стартовой экспортируемой из DLL функции. Соответственно при изменении названия файла библиотеки необходимо менять и имя стартовой функции.

На самом деле можно. Только версию надо писать через дефис и без точек: w32-5_4.dll. У require есть фича отбрасывать в имени dll все, что после дефиса при поиске функции luaopen_*.

require("w32-5_4")

Это работает, проверьте.