Re: Создание собственной DLL на C++ для LUA (в QUIK)
-
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
QUIK -> DDE → Написание внешних библиотек на C++/Delphi/C# для Lua → Создание собственной DLL на C++ для LUA (в QUIK)
-
Привет всем!
Я тут немного покопался в документации и разобрался как посылать таблицы в dll и возвращать их обратно в lua. Может кому-нибудь пригодится:
Вызов из луа:
tab = { {x = 2.79, k = 13, s = 'xxxx', fl = true}, {x = 1.79, k = 23, s = 'yyyy', fl = false} }
tab1, tab2 = MyLib.testFunc( 2.79, 13, tab, 'asdf', true )
for index, struct in pairs(tab1) do
print( index )
for key, val in pairs(struct) do
print( key, '=', val )
end
end
for index, struct in pairs(tab2) do
print( index )
for key, val in pairs(struct) do
print( key, '=', val )
end
end
вывод скрипта:
3
s = asdf
x = 2.79
k = 13
fl = true
5
k = 13
x = 2.79
s = asdf
fl = true
1
str = xxxx
num = 16.79
2
str = yyyy
num = 24.79
Код функции в dll:
struct someDataFromLua
{
double x;
int k;
const char* s;
bool fl;
};
// Args: double x, int k, /*table book, */string s, bool fl
static int testFunc( lua_State* L )
{
double x = lua_tonumber( L, 1 );
int k = lua_tointeger( L, 2 );
const char* s = lua_tostring( L, 4 );
int fl = lua_toboolean( L, 5 );
lua_createtable( L, 2, 0 );
lua_pushstring( L, "3" );
lua_createtable( L, 4, 0 );
lua_pushstring( L, "x" );
lua_pushnumber( L, x );
lua_settable( L, -3 );
lua_pushstring( L, "k" );
lua_pushinteger( L, k );
lua_settable( L, -3 );
lua_pushstring( L, "s" );
lua_pushstring( L, s );
lua_settable( L, -3 );
lua_pushstring( L, "fl" );
lua_pushboolean( L, fl );
lua_settable( L, -3 );
lua_settable( L, -3 );
lua_pushstring( L, "5" );
lua_createtable( L, 4, 0 );
lua_pushstring( L, "fl" );
lua_pushboolean( L, fl );
lua_settable( L, -3 );
lua_pushstring( L, "s" );
lua_pushstring( L, s );
lua_settable( L, -3 );
lua_pushstring( L, "k" );
lua_pushinteger( L, k );
lua_settable( L, -3 );
lua_pushstring( L, "x" );
lua_pushnumber( L, x );
lua_settable( L, -3 );
lua_settable( L, -3 );
unsigned tabLen = lua_objlen( L, 3 );
someDataFromLua* pData = new someDataFromLua[tabLen];
lua_pushnil( L );
unsigned i = 0;
while( lua_next( L, 3 ) != 0 && i < tabLen ) // ...and pushes nothing
{
lua_getfield( L, -1, "x" );
pData[i].x = lua_tonumber( L, -1 );
lua_getfield( L, -2, "k" );
pData[i].k = lua_tointeger( L, -1 );
lua_getfield( L, -3, "s" );
pData[i].s = lua_tostring( L, -1 );
lua_getfield( L, -4, "fl" );
pData[i].fl = lua_toboolean( L, -1 ) != 0;
lua_pop( L, 5 );
++i;
}
lua_createtable( L, tabLen, 0 );
for( i = 0; i < tabLen; i++ )
{
lua_pushinteger( L, int(i) + 1 );
lua_createtable( L, 2, 0 );
lua_pushstring( L, "str" );
lua_pushstring( L, pData[i].s );
lua_settable( L, -3 );
lua_pushstring( L, "num" );
lua_pushnumber( L, pData[i].x + double( pData[i].k ) + double( pData[i].fl ) ); // считаем сумму x + k + fl чтобы вывод занимал меньше места
lua_settable( L, -3 );
lua_settable( L, -3 );
}
return 2;
}
Полностью скопировал ваш код.
Делаю Build Solution
Посыпались такие ошибки. Подскажите что делать.
Полностью скопировал ваш код.
Делаю Build Solution
Посыпались такие ошибки.
Подозреваю, что пропущен вот этот шаг:
И ещё: файл lua5.1.dll не надо добавлять в solution, уберите его.
Здравствуйте, помогите, пожалуйста разобраться, что только не делал:
пытался собирать свою(вашу) длл под VS2008
брал уже вами собранные DLL и скрипт lua
пробовал сторонние длл
даже переустанавливал квик
все в пустую - одна и та же ошибка не видит скрипт(и с указанными дирректориями и просто поставелнными в корень файлами к ИНФО)
ошибка:
C:\SB\luacdll.lua:1: loop or previous error loading module 'luacdll'
или
error loading module
система MS Vista quik - от сбера
dkpkfx, такое предложение.
Возьмите вашу папку QUIK, из неё скопируйте все только exe и dll файлы (т.е. без dat/log файлов и файлов ключей, где содержится ваша информация)
И Lua-скрипт ваш проблемный.
Всё это запакуйте в архив (все как у вас есть, если какие-то папки / подпапки - то вместе с ними, но только dll и exe файлы!) и пришлите на почту swerg@swerg.ru
Постараюсь разобраться.
Ну потому как по описанию - не понятно совершенно. Особенно если вы говорите, что берёте уже собранную dll.
Кстати, вопрос: QUIK какой версии у вас?
Вы dll правильной разрядности подкладываете? (x86 для QUIK7 и x64 для QUIK8)
К сожалению, я не дополнил описание про варианты сборки x64, но выложенный на данный момент архив исходников содержит оба варианта сборки, надо только выбрать верный вариант в зависимости от версии QUIK, которым вы пользуетесь.
(Обновлено 12.07.2019 -
static struct luaL_reg ls_lib[] = {
.
Вообщем напротив этой строчки компилятор постоянно лупит мне ошибку - недопустимый неполный тип, подчеркивая красным
ls_lib, делал все один в один по вашему примеру, ничего лишнего - в чем ошибка? У вас то этот пример рабочий хоть?
Я в Си еще новичек сам разобраться не могу пока
Nordman, да, все приведённые здесь примеры абсолютно рабочие.
Разумеется, в теме я не пишу полные исходники, лишь части, которые требуют пояснения из полного текста исходников.
Возьмите полные исходники по ссылке на GitHub и сделайте на их основе нужную вам библиотеку. Взять за основу и переделать - будет много проще, здесь в примерах уже всё настроено в C++ проекте для компиляции: подключаются нужные заголовочные файлы Lua в зависимости от требуемой версии терминала, нужные для сборки библиотеки опять же в зависимости от требуемой версии терминала - и т.д.
Что касается указанной вами ошибки: возможно, вы в своём проекте не подключили заголовочные файлы Lua через #include, от того и ошибка.
Это всё есть в архиве в исходниках приложенных примеров.
Доброго дня!
Аналогичная ошибка : ".\luacdll.lua:1: loop or previous error loading module 'luacdll'"
Использовал как предкомпилированную luacdll.dll из архива, так и скомпилированную Visual Studio dll.
Lua файл без изменений - из архива.
У вас рекомендовано скопировать lua5.1.dll в ту же директорию, где info.exe и файлы плагина lua, но он там и так имеется.
Попробовал влоб dumpbin.exe / lib.exe и создать новую .lib из lua5.1.dll из поставки QUIK. Интересный эффект - размер скомпилированного файла dll c применением .lib из вашего архива отличается от размера dll с новым .lib файлом. Но эффект тот же - сообщение об ошибке.
Для чистоты эксперимента попробовал в разных версиях терминала разных брокеров, включая Сбер.
В чём проблема? Не удалось ли вам найти?
В исходном коде добавлена конфигурация для QUIK 8.5 (Lua 5.3)
Ссылка на GitHub в первом сообщении.
Запустил lua с вашей dll luacdll написаной и скомпилированной для lua5.3 в lua скрипте ошибка на строке require("luacdll") error loading module 'luacdll' from file '.\luacdll.lua':
.\luacdll.lua:1: too many C levels (limit is 200) in main function near '"luacdll"'
Quik версии 8.6.0.97 брал вашу релизную конфигурацию 5.3 Подскажите в чем дело?
С уважением Громазин Николай
Запустил lua с вашей dll luacdll написаной и скомпилированной для lua5.3 в lua скрипте ошибка на строке require("luacdll") error loading module 'luacdll' from file '.\luacdll.lua':
.\luacdll.lua:1: too many C levels (limit is 200) in main function near '"luacdll"'
Quik версии 8.6.0.97 брал вашу релизную конфигурацию 5.3 Подскажите в чем дело?
С уважением Громазин Николай
см. ниже п.9 - должно заработать
Опишу всю процедуру для QUIK 8.8.4.3 (lua5.3) и MS VS 2019 Community (бесплатная)
1. Создаем новый пустой C++-проект с именем "lua_dll_x64_name" (одно имя для проекта и решения)
2. Добавляем пустой cpp-файл в раздел "Исходные файлы" с тем же именем - "lua_dll_x64_name.cpp" (в Обозревателе решений щелкаем правой клавишей мыши на "Исходные файлы" и выбираем Добавить/Создать элемент/Класс C++)
3. MS VS 2019 должен был создать для этого проекта папку lua_dll_x64_name в которой теперь пора создать папку Lua
3. Скачиваем с [url]https://sourceforge.net/projects/luabinaries/files/5.3.5/Windows%20Libraries/Static/[/url] архив "lua-5.3.5_Win64_vc16_lib.zip" и распаковываем в lua_dll_x64_name/Lua
4. В Обозревателе решений щелкаем правой клавишей мыши на "Заголовочные файлы" и выбираем Добавить/Существующий элемент... и указать из папки lua_dll_x64_name/Lua все .h- и .hpp-файлы.
7. Открыть Диспетчер конфигураций и установить x64 для Debug и Release (можно ч/з соответствующие окошки в панели инструментов)
8. Настраиваем свойства проекта (для Release и Debug устанавливаются отдельно!!!). Окно свойств вызывается в Обозревателе решений щелчком правой клавишей мыши на имени проекта "lua_dll_x64_name"
- Общие/Тип конфигурации: "Динамическая библиотека (.dll)"
- Дополнительно/Набор символов: "Использовать набор символов Юникода"
- Дополнительно/Поддержка общеязыковой среды выполнения (CLR): "Без поддержки CLR-среды"
- Компоновщик/Ввод/Дополнительные зависимости/<Изменить...>: вписать Lua\lua53.lib <OK>
- C/C++/Создание кода/Библиотека времени выполнения: Release/Debug - "Многопоточная (/MT)"/"Многопоточная отладка (/MTd)"
8. Добавьте в пока пустой файл исходного кода (lua_dll_x64_name.cpp) следующие строки:
#include <windows.h>
//=== Необходимые для Lua константы ============================================================================//
#define LUA_LIB
#define LUA_BUILD_AS_DLL
//=== Заголовочные файлы LUA ===================================================================================//
extern "C" {
#include "Lua\lauxlib.h"
#include "Lua\lua.h"
}
//=== Стандартная точка входа для DLL ==========================================================================//
BOOL APIENTRY DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved) {
return TRUE;
}
//=== Реализация функций, вызываемых из LUA ====================================================================//
static int forLua_TestFunc(lua_State* L){
lua_pushstring(L, "Привет из C/C++");
return(1);
}
//=== Регистрация реализованных в dll функций, чтобы они стали "видимы" для Lua ================================//
static struct luaL_Reg ls_lib[] = {
{"TestFunc", forLua_TestFunc},
{NULL, NULL}
};
//=== Регистрация названия библиотеки, видимого в скрипте Lua ==================================================//
extern "C" LUALIB_API int luaopen_lua_dll_x64_name(lua_State * L) {
lua_newtable(L);
luaL_setfuncs(L, ls_lib, 0);
lua_pushvalue(L, -1);
lua_setglobal(L, "lua_dll_x64_name");
return 0;
}
9. В lua-скрипте пишем следующее:
path = getScriptPath() .. "\\lua_dll_x64_name.dll"
package.loadlib(path, "luaopen_lua_dll_x64_name")()
function main()
message(lua_dll_x64_name.TestFunc())
end
Опишу всю процедуру для QUIK 8.8.4.3 (lua5.3) и MS VS 2019 Community (бесплатная)
.....
Эх, опыту у меня маловато...Набрал пример, как описано выше VS 2019 Community. При запуске Lua- программы через QUIK-Junior (версия 8.9.0.107) получаю ошибку:
lua:2:attempt to call a nill value
Подскажите, пожалуйста, как проверить, где находится ошибка, в первом параметре, или во втором?
получаю ошибку:
lua:2:attempt to call a nill value
Подскажите, пожалуйста, как проверить, где находится ошибка, в первом параметре, или во втором?
А где лежит собранная вами dll? в каком каталоге?
Попробуйте положить dll в каталог с QUIK (туда же, где info.exe) выполнить такой Lua-скрипт:
lua_dll_x64_name = require("lua_dll_x64_name")
message(lua_dll_x64_name.TestFunc())
Ага, все сразу стало на свои места. Косо собрал библиотеку.
Спасибо за совет. Пересобрал библиотеку и пример заработал.
Добрый день. Немного глупый вопрос может показаться, но как открыть* DLL с бинарным кодом найденного на просторах интернета lua скрипта, чтобы изучить код и внести свои коррективы? Спасибо
*под Win 10 x64 или Mac OS Catalina
как открыть* DLL с бинарным кодом найденного на просторах интернета lua скрипта
Тут бы подробнее, что за "с бинарным кодом найденного на просторах интернета lua скрипта" ?
Кто-нибудь пробовал собирать под MSYS2 ? У меня собирается, но под квиком не работает... Подозреваю, что не нравится компилятору lua53.lib . Не подскажите, можно где-то достать исходный код этой библиотеки?
Не подскажите, можно где-то достать исходный код этой библиотеки?
очевидно, тут: [url]https://www.lua.org/ftp/[/url]
Подозреваю, что не нравится компилятору lua53.lib . Не подскажите, можно где-то достать исходный код этой библиотеки?
Если дело действительно в lua53.lib, то на самом деле она вам не очень-то и нужна, и уж точно не нужны её исходники для использования своих библиотек в QUIK.
Эта библиотека - это реализация функций Lua. Однако фактически никакой реализации этих функций вам не требуется, т.к. все они реализованы в lua53.dll, а lua53.lib - это лишь удобная обертка для импорта статического импорта функций, реализованных в lua53.dll. так называемая import library.
Т.е. на самом деле вы можете все функции интерфейсные Lua динамически загрузить из lua53.dll при старте вашей библиотеки через GetProcAddress.
Либо изготовить lua53.lib самостоятельно утилитами из состава MSYS2 (наверняка там такое есть).
(Для MS VS эта самая lua53.lib не компилируется, а "изготавливается" на основе lua53.dll утилитами, входящими в состав MS VS, если говорить про сборку своих dll для использования в QLua.)
PS
Из гугления у меня сложилось впечатление, что надо просто установит готовый подходящий пакет Lua-библиотек для mingw
Вероятно что-то вроде такого, только с версией Lua разобраться.
[url]https://packages.msys2.org/package/mingw-w64-x86_64-lua[/url]
собирается, но под квиком не работает...
Как это выглядит? что значит "не работает"? ошибку какую-то выдает или что?
//=== Стандартная точка входа для DLL ==========================================================================// BOOL APIENTRY DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved) { return TRUE; }
Это не требуется в варианте LUA и VC++
Добрый день!
Подскажите, можно ли использовать в Lua методы и атрибуты классов из DLL?
Если да, то как?
Мне нужно загрузить предобученную модель (файл) в нейронную сеть, скомпилированную в DLL, и потом использовать эту модель для прогноза.
allesid,
Вызвать можно, но вызвать метод C++ класса напрямую из Lua - не получится.
Из Lua вызываются функции специальной сигнатуры вида
int forLua_TestFunc(lua_State* L)
{...}
Т.е. надо просто сделать стандартные для С-интерфейса Lua "обёртки" для обращения к нужным вам методам / классам C++.
Либо сделать обертку для C++ класса в виде метатаблицы для Lua, это уже зависит от желаемой эстетики
В любом случае небольшую обёрточку надо сделать.
Посмотрите приведенные на этом сайте примеры, там все просто.
inf.sbb пишет:получаю ошибку:
lua:2:attempt to call a nill value
Подскажите, пожалуйста, как проверить, где находится ошибка, в первом параметре, или во втором?А где лежит собранная вами dll? в каком каталоге?
Попробуйте положить dll в каталог с QUIK (туда же, где info.exe) выполнить такой Lua-скрипт:
lua_dll_x64_name = require("lua_dll_x64_name") message(lua_dll_x64_name.TestFunc())
Не могли бы Вы подсказать ?
Сделал, как в Вашем примере:
Visual Studio создала dll ---> "lua_dll_x64_name.dll" - компилировал, как debug x64.
Скопировал "lua_dll_x64_name.dll" в папку с quik, где находится файл Info.exe и запустил скрипт:
lua_dll_x64_name = require("lua_dll_x64_name")
message(lua_dll_x64_name.TestFunc())
Но quik выдает ошибку:
Lua_script.lua.txt:3: attempt to index a boolean value (global 'lua_dll_x64_name')
QUIK -> DDE → Написание внешних библиотек на C++/Delphi/C# для Lua → Создание собственной DLL на C++ для LUA (в QUIK)
Форум работает на PunBB, при поддержке Informer Technologies, Inc