Коннектор 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++ и тип проекта "Пустой проект". Создайте новую папку для проекта, если необходимо.

[su_spoiler title="В Visual Studio Community 2013 это выглядит следующим образом:" style="fancy"]Создание пустого проекта в VS
[/su_spoiler]

[su_spoiler title="В результате, Visual Studio создаст решение и один проект в нем:" style="fancy"]Пустой проект
[/su_spoiler]

[su_spoiler title="Сейчас можно добавить в проект файл исходного кода" style="fancy"]
Для этого, в "Обозревателе решений", в папке проекта, нужно кликнуть правой кнопкой мыши по папке "Файлы исходного кода" и пройти: "Добавить" -> "Создать элемент":
Создание-файла-исходного-кода
Далее, выбираем тип файла "Файл C++" из вкладки "Visual C++":
Новый-файл-C++
Можно назвать его так же, как проект, чтобы не путаться. После нажатия на кнопку "Добавить" в проекте, в папке "Файлы исходного кода" появится пустой файл исходного кода C/C++.
[/su_spoiler]

[su_spoiler title="Следующим шагом необходимо добавить в проект заголовочные файлы и библиотеку Lua" style="fancy"]
Для этого, скачайте данный архив, в нем, в папке "Lua" находятся следующие файлы: lauxlib.h, lua.h, luaconf.h и lua5.1.lib. Извлеките эту папку из архива и поместите в одной папке с файлом исходного кода C++, как показано на изображении:
Заголовочные-файлы-Lua
Сейчас можно добавить их в проект, для этого нужно в "Обозревателе решений" кликнуть правой кнопкой мыши по папке "Заголовочные файлы" и далее выбрать: "Добавить" -> "Существующий элемент..."
Добавить-заголовочные-файлы
Откройте добавленную папку "Lua", выделите, зажав кнопку "Ctrl", 3 заголовочных файла, как показано на изображении, и нажмите кнопку "Добавить".
Выделение-файлов
[/su_spoiler]

[su_spoiler title="Далее, нужно настроить свойства проекта:" style="fancy"]
Для этого, нужно правой кнопкой мыши кликнуть по названию проекта (не решения) и выбрать "Свойства":
Проект-свойства
Откроется окно свойств, в котором нужно "Тип конфигурации" установить, как "Динамическая библиотека (.dll)":
Свойства-тип-конфигурации-dllУбедитесь, что в поле "Набор символов" установлено значение "Использовать набор символов Юникода".

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

[su_spoiler title="Добавление базового кода" style="fancy"]
Добавьте в файл исходного кода следующие строки:

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++, ознакомьтесь с данной статьей.

[/su_spoiler]

[su_spoiler title="Сейчас можно 'Собрать' проект" style="fancy"]
Если кликнуть правой кнопкой мыши по папке проекта и нажать на пункт меню "Собрать",
Собрать-проект
то, после компиляции, в папке с терминалом появиться новая библиотека DLL, которая будет называться так же, как проект, и еще несколько сервисных файлов Visual Studio, которые не нужны для работы библиотеки, но и мешать работе терминала не будут.
[/su_spoiler]

[su_spoiler title="Использование библиотеки DLL в скрипте QLua(Lua)" style="fancy"]
ВАЖНО!!! Название 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++".
[/su_spoiler]
Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!