Коннектор DLL QUIK - QLua(Lua) - C++

Автор записи: Дмитрий (Admin)

Qlua-csharp-connector-dll
Для Quik 8 x64 (Lua 5.1) скачать готовое решение VS 2019 Community можно по этой ссылке 
Для Quik 8 x64 (Lua 5.3.5) скачать готовое решение VS 2019 Community можно по этой ссылке

Для того, чтобы обмениваться данными между скриптом Qlua и приложением на C# требуется библиотека DLL, написанная на языке C/C++. Для этого в Visual Studio нужно "Создать проект", выбрав язык C++ и тип проекта "Пустой проект". Создайте новую папку для проекта, если необходимо.

В Visual Studio Community 2013 это выглядит следующим образом:
Создание пустого проекта в VS
В результате, Visual Studio создаст решение и один проект в нем:
Пустой проект
Сейчас можно добавить в проект файл исходного кода
Для этого, в «Обозревателе решений», в папке проекта, нужно кликнуть правой кнопкой мыши по папке «Файлы исходного кода» и пройти: «Добавить» -> «Создать элемент»:
Создание-файла-исходного-кода
Далее, выбираем тип файла «Файл C++» из вкладки «Visual C++»:
Новый-файл-C++
Можно назвать его так же, как проект, чтобы не путаться. После нажатия на кнопку «Добавить» в проекте, в папке «Файлы исходного кода» появится пустой файл исходного кода C/C++.
Следующим шагом необходимо добавить в проект заголовочные файлы и библиотеку Lua
Для этого, скачайте данный архив, в нем, в папке «Lua» находятся следующие файлы: lauxlib.h, lua.h, luaconf.h и lua5.1.lib. Извлеките эту папку из архива и поместите в одной папке с файлом исходного кода C++, как показано на изображении:
Заголовочные-файлы-Lua
Сейчас можно добавить их в проект, для этого нужно в «Обозревателе решений» кликнуть правой кнопкой мыши по папке «Заголовочные файлы» и далее выбрать: «Добавить» -> «Существующий элемент…»
Добавить-заголовочные-файлы
Откройте добавленную папку «Lua», выделите, зажав кнопку «Ctrl», 3 заголовочных файла, как показано на изображении, и нажмите кнопку «Добавить».
Выделение-файлов
Далее, нужно настроить свойства проекта:
Для этого, нужно правой кнопкой мыши кликнуть по названию проекта (не решения) и выбрать «Свойства»:
Проект-свойства
Откроется окно свойств, в котором нужно «Тип конфигурации» установить, как «Динамическая библиотека (.dll)»:
Свойства-тип-конфигурации-dllУбедитесь, что в поле «Набор символов» установлено значение «Использовать набор символов Юникода».

В поле «Поддержка общеязыковой среды выполнения (CLR)» должно быть значение «Без поддержки CLR-среды»:
Без-поддержки-CLR-среды
Для того, чтобы скрипт Qlua мог работать с библиотекой DLL, она должна находится в корневом каталоге терминала QUIK. По-этому, в поле «Выходной каталог» можно сразу указать папку с терминалом QUIK, тогда библиотека будет компилироваться сразу в нее и, в последствии, после внесения каких-либо изменений, не придется постоянно заменять старую DLL на новую:
Выходной-каталог-dll
Далее, нужно перейти: «Свойства конфигурации» -> «Компоновщик» -> «Ввод». В поле «Дополнительные зависимости» из выпадающего списка выбрать пункт «<Изменить…>».
Дополнительные-зависимости
В открывшемся окне в верхнее поле добавить строку «Lua\lua5.1.lib» и нажать кнопку «ОК»
Дополнительные-зависимости-изменить
Теперь осталось нажать кнопки «Применить» и «ОК».

Добавление базового кода
Добавьте в файл исходного кода следующие строки:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#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)
{
   //Каждому событию соответствует свое значение аргумента fdwReason, передаваемого функции DllMain при его возникновении
   switch (fdwReason)
   {
      case DLL_PROCESS_ATTACH: // Подключение DLL
         break;
      case DLL_PROCESS_DETACH: // Отключение DLL
         break;
      case DLL_THREAD_ATTACH:  // Создание нового потока
         break;
      case DLL_THREAD_DETACH:  // Завершение потока
         break;
   }
   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 }, // из скрипта Lua эту функцию можно будет вызывать так: QluaCSharpConnector.TestFunc(); здесь можно указать любое другое название
   { NULL, NULL }
};
 
//=== Регистрация названия библиотеки, видимого в скрипте Lua ==================================================//
extern "C" LUALIB_API int luaopen_QluaCSharpConnector(lua_State *L) {
   luaL_openlib(L, "QluaCSharpConnector", ls_lib, 0);
   return 0;
}

Для того, чтобы узнать как Lua может взаимодействовать с библиотекой DLL, написанной на C/C++, ознакомьтесь с данной статьей.

Сейчас можно 'Собрать' проект
Если кликнуть правой кнопкой мыши по папке проекта и нажать на пункт меню «Собрать»,
Собрать-проект
то, после компиляции, в папке с терминалом появиться новая библиотека DLL, которая будет называться так же, как проект, и еще несколько сервисных файлов Visual Studio, которые не нужны для работы библиотеки, но и мешать работе терминала не будут.
Использование библиотеки DLL в скрипте QLua(Lua)
ВАЖНО!!! Название Qlua — скрипта не должно совпадать с именем DLL.
Для этого нужно в начало файла добавить следующую строку: «require(«QluaCSharpConnector»);». Таким образом функции библиотеки можно будет использовать в скрипте.
Пример обращения к функции, ранее созданной библиотеки:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
require("QluaCSharpConnector");
 
IsRun = true;
 
function main()
   while IsRun do
      sleep(1000);
   end;
end;
 
function OnStop()
 
   message(QluaCSharpConnector.TestFunc());
 
   IsRun = false;
end;

Данный скрипт выведет сообщение с текстом: «Привет из C/C++».

Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!