51 (2016-09-29 11:42:02 отредактировано sam063rus)

Re: Создание собственной DLL на C++ для LUA (в QUIK)

-

52 (2016-11-28 01:31:43 отредактировано slavon)

Re: Создание собственной 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;
}

53

Re: Создание собственной DLL на C++ для LUA (в QUIK)

Полностью скопировал ваш код.
Делаю Build Solution
Посыпались такие ошибки. Подскажите что делать.
http://dl4.joxi.net/drive/2018/08/16/0011/1313/742689/89/4a734dd8f7.png

54

Re: Создание собственной DLL на C++ для LUA (в QUIK)

astro-12 пишет:

Полностью скопировал ваш код.
Делаю Build Solution
Посыпались такие ошибки.

Подозреваю, что пропущен вот этот шаг:
https://quik2dde.ru/static-img/cpp_lua-2-01.png

И ещё: файл lua5.1.dll не надо добавлять в solution, уберите его.

55 (2019-10-07 22:51:11 отредактировано dkpkfx)

Re: Создание собственной DLL на C++ для LUA (в QUIK)

Здравствуйте, помогите, пожалуйста разобраться, что только не делал:

пытался собирать свою(вашу) длл под VS2008
брал уже вами собранные  DLL и скрипт lua
пробовал сторонние длл
даже переустанавливал квик

все в пустую - одна и та же ошибка не видит скрипт(и с указанными дирректориями и просто поставелнными в корень файлами к ИНФО)

ошибка:
C:\SB\luacdll.lua:1: loop or previous error loading module 'luacdll'
или
error loading module

система MS Vista quik - от сбера

56 (2019-10-08 09:44:14 отредактировано swerg)

Re: Создание собственной DLL на C++ для LUA (в QUIK)

dkpkfx, такое предложение.
Возьмите вашу папку QUIK, из неё скопируйте все только exe и dll файлы (т.е. без dat/log файлов и файлов ключей, где содержится ваша информация)
И Lua-скрипт ваш проблемный.

Всё это запакуйте в архив (все как у вас есть, если какие-то папки / подпапки - то вместе с ними, но только dll и exe файлы!) и пришлите на почту swerg@swerg.ru

Постараюсь разобраться.
Ну потому как по описанию - не понятно совершенно. Особенно если вы говорите, что берёте уже собранную dll.

Кстати, вопрос: QUIK какой версии у вас?
Вы dll правильной разрядности подкладываете? (x86 для QUIK7 и x64 для QUIK8)

К сожалению, я не дополнил описание про варианты сборки x64, но выложенный на данный момент архив исходников содержит оба варианта сборки, надо только выбрать верный вариант в зависимости от версии QUIK, которым вы пользуетесь.

57

Re: Создание собственной DLL на C++ для LUA (в QUIK)

admin пишет:

(Обновлено 12.07.2019 -
static struct luaL_reg ls_lib[] = {
.

Вообщем напротив  этой строчки компилятор постоянно лупит мне ошибку - недопустимый неполный тип, подчеркивая красным
ls_lib, делал все один в один по вашему примеру, ничего лишнего - в чем ошибка? У вас то этот пример рабочий хоть?
Я в Си еще новичек сам разобраться не могу пока

58 (2020-05-20 09:36:29 отредактировано swerg)

Re: Создание собственной DLL на C++ для LUA (в QUIK)

Nordman, да, все приведённые здесь примеры абсолютно рабочие.
Разумеется, в теме я не пишу полные исходники, лишь части, которые требуют пояснения из полного текста исходников.
Возьмите полные исходники по ссылке на GitHub и сделайте на их основе нужную вам библиотеку. Взять за основу и переделать - будет много проще, здесь в примерах уже всё настроено в C++ проекте для компиляции: подключаются нужные заголовочные файлы Lua в зависимости от требуемой версии терминала, нужные для сборки библиотеки опять же в зависимости от требуемой версии терминала - и т.д.

Что касается указанной вами ошибки: возможно, вы в своём проекте не подключили заголовочные файлы Lua через #include, от того и ошибка.
Это всё есть в архиве в исходниках приложенных примеров.

59 (2020-04-29 05:10:37 отредактировано MXQTFINANCE)

Re: Создание собственной DLL на C++ для LUA (в QUIK)

Доброго дня!
Аналогичная ошибка : ".\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 файлом. Но эффект тот же - сообщение об ошибке.
Для чистоты эксперимента попробовал в разных версиях терминала разных брокеров, включая Сбер.

В чём проблема? Не удалось ли вам найти?

60

Re: Создание собственной DLL на C++ для LUA (в QUIK)

В исходном коде добавлена конфигурация для QUIK 8.5 (Lua 5.3)
Ссылка на GitHub в первом сообщении.

61

Re: Создание собственной DLL на C++ для LUA (в QUIK)

Запустил 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 Подскажите в чем дело?
С уважением Громазин Николай

62 (2020-09-21 14:17:56 отредактировано Виктор Шабунин)

Re: Создание собственной DLL на C++ для LUA (в QUIK)

sundancer0369 пишет:

Запустил 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. Скачиваем с https://sourceforge.net/projects/luabin … es/Static/ архив "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