Виклик функцій QLua (Lua) з DLL, написаної на C / C ++
Для цього потрібна звичайна бібліотека DLL, що підключається до QLua, про те, як її створити можете подивитися тут .
Нехай створена Вами DLL називається "LuaCallback.dll", яка знаходиться в кореневому каталозі терміналу QUIK.
Наступний приклад 10 разів, з періодичністю в 1 секунду виведе повідомлення з текстом "Привіт з DLL" за допомогою виклику з DLL функції з Qlua скрипта MyLuaCallback ():
Код скрипта QLua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 require ( "LuaCallback"); - Включає бібліотеку "LuaCallback.dll" Run = true; - Прапор підтримки роботи скрипта - Основна функція скрипта, поки працює вона, працює скрипт function main () LuaCallback .StartCallback (); - Запускає механізм виклику функції MyLuaCallback з DLL while Run do sleep (1000); end; - Підтримує роботу скрипта end; - Функція, що викликається з DLL function MyLuaCallback (Text) message (Text); - Виводить повідомлення, передане в функцію з DLL end; - Функція завершення роботи скрипта function OnStop () Run = false; - Завершує цикл while, отже завершується main () і сам скрипт зупиняється end;
код DLL
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 50 51 52 53 54 55 #include <Windows.h> // Включає все необхідне #include <thread> // Включає можливість роботи з потоками // === Необхідні для 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 ul_reason_for_call, LPVOID lpReserved) {return TRUE; } // Функція викликає функцію з QLua з періодичністю в 1 секунду static int MyCallback (lua_State * L) {lua_getglobal (L, "MyLuaCallback"); // Знаходить в стеці Lua функцію по її назві і поміщає її наверх стека int callbackRef = luaL_ref (L, LUA_REGISTRYINDEX); // Отримує індекс функції в спеціальній внутрішньої таблиці (реєстр) Lua for (int i = 0; i <10; i ++) {lua_rawgeti (L, LUA_REGISTRYINDEX, callbackRef); // Дістає функцію з реєстру Lua за індексом і поміщає в стек lua_pushstring (L, "Привіт з DLL"); // Додає в стек параметр, який буде переданий функції lua_call (L, 1, 1); // Викликає обрану функцію в скрипті QLua, передаючи в неї 1 параметр (L - стек, 1 - кількість переданих параметрів, 1 - кількість значень, що повертаються (потрібно, щоб оновлювати стек)) Sleep (1000); // Пауза в 1 секунду} return 0; // Вихід з функції} // === Реалізація функцій, що викликаються з LUA ================================= =================================== // static int forLua_StartCallback (lua_State * L) {std :: thread thr (MyCallback, L); // Запускає виконання функції MyCallback () в окремому потоці thr. detach (); // від'єднується створений потік від основного, роблячи його "фоновим" return (0); // Завершує роботу функції forLua_StartCallback, при цьому функція MyCallback продовжує працювати в окремому потоці} // === Реєстрація реалізованих в dll функцій, щоб вони стали "видимі" для Lua ============== ================== // static struct luaL_reg ls_lib [] = {{ "StartCallback", forLua_StartCallback}}; // === Реєстрація назви бібліотеки, видимого в скрипті Lua ===================================== ============= // extern "C" LUALIB_API int luaopen_LuaCallback (lua_State * L) {luaL_openlib (L, "LuaCallback", ls_lib, 0); return 0; }
Якщо у Вас з'явилися якісь питання, задайте їх в коментарях під статтею !!!