Таким образом можно любую встроенную в QLua функцию заменить функцией в DLL, в результате скрипт QLua может содержать только одну строку подключения библиотеки, а всю обработку можно вынести в DLL, а из нее в C#.
1 2 3 4 5 6 7 8 9 10 11 12 13 | require("QLuaCallbacks"); Run = true; function main() while Run do sleep(1); end; end; function OnStop() Run = false; end; |
require("QLuaCallbacks"); Run = true; function main() while Run do sleep(1); end; end; function OnStop() Run = false; end;
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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | #include <windows.h> #include <string> //=== Необходимые для 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; } struct DateTime { int mcs; //Микросекунды int ms; //Миллисекунды int sec; //Секунды int min; //Минуты int hour; //Часы int day; //День int week_day; //Номер дня недели int month; //Месяц int year; //Год }; std::string getFieldValue(lua_State *L, const char *key) { std::string result; lua_pushstring(L, key); /* поместить ключ на стек */ lua_gettable(L, -2); /* получить значение */ result = lua_tostring(L, -1); lua_pop(L, 1); return result; } DateTime getDateTimeField(lua_State *L) { DateTime datetime; lua_pushstring(L, "datetime"); /* поместить ключ на стек */ lua_gettable(L, -2); /* получить таблицу datetime */ lua_pushstring(L, "mcs"); //Микросекунды lua_gettable(L, -2); datetime.mcs = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "ms"); //Миллисекунды lua_gettable(L, -2); datetime.ms = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "sec"); //Секунды lua_gettable(L, -2); datetime.sec = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "min"); //Минуты lua_gettable(L, -2); datetime.min = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "hour"); //Часы lua_gettable(L, -2); datetime.hour = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "day"); //День lua_gettable(L, -2); datetime.day = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "week_day"); //Номер дня недели lua_gettable(L, -2); datetime.week_day = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "month"); //Месяц lua_gettable(L, -2); datetime.month = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "year"); //Год lua_gettable(L, -2); datetime.year = lua_tonumber(L, -1); lua_pop(L, 1); lua_pop(L, 1); return datetime; } //=== Реализация функций обратного вызова ====================================================================// static int forLua_OnAllTrade(lua_State *L) // { // Проверяет, является-ли первый элемент стека массивом (таблицей Lua) if (lua_istable(L, 1)) { std::string trade_num = getFieldValue(L, "trade_num"); // Номер сделки в торговой системе std::string flags = getFieldValue(L, "flags"); // Набор битовых флагов std::string price = getFieldValue(L, "price"); // Цена std::string qty = getFieldValue(L, "qty"); // Количество бумаг в последней сделке в лотах std::string value = getFieldValue(L, "value"); // Объем в денежных средствах std::string accruedint = getFieldValue(L, "accruedint"); // Накопленный купонный доход std::string yield = getFieldValue(L, "yield"); // Доходность std::string settlecode = getFieldValue(L, "settlecode"); // Код расчетов std::string reporate = getFieldValue(L, "reporate"); // Ставка РЕПО(%) std::string repovalue = getFieldValue(L, "repovalue"); // Сумма РЕПО std::string repo2value = getFieldValue(L, "repo2value"); // Объем выкупа РЕПО std::string repoterm = getFieldValue(L, "repoterm"); // Срок РЕПО в днях std::string sec_code = getFieldValue(L, "sec_code"); // Код бумаги заявки std::string class_code = getFieldValue(L, "class_code"); // Код класса DateTime datetime = getDateTimeField(L); // Дата и время std::string period = getFieldValue(L, "period"); // Период торговой сессии.Возможные значения : «0» – Открытие; «1» – Нормальный; «2» – Закрытие if (sec_code == "SBER") { std::string TradeInfo = "trade_num=" + trade_num + " " + "flags=" + flags + " " + "price=" + price + " " + "qty=" + qty + " " + "value=" + value + " " + "accruedint=" + accruedint + " " + "yield=" + yield + " " + "settlecode=" + settlecode + " " + "reporate=" + reporate + " " + "repovalue=" + repovalue + " " + "repo2value=" + repo2value + " " + "repoterm=" + repoterm + " " + "sec_code=" + sec_code + " " + "class_code=" + class_code + " " + "time=" + std::to_string(datetime.hour) + ":" + std::to_string(datetime.min) + ":" + std::to_string(datetime.sec) + "." + std::to_string(datetime.mcs) + " " + "trade_num=" + trade_num + " " + "period=" + period; //Выводит сообщение в терминале с информацией по сделке lua_getglobal(L, "message"); lua_pushfstring(L, TradeInfo.c_str()); lua_pcall(L, 1, 0, 0); } } return 0; } //=== Регистрация реализованных в dll функций, чтобы они стали "видимы" для Lua ================================// static struct luaL_reg ls_lib[] = { { NULL, NULL } }; //=== Регистрация названия библиотеки, видимого в скрипте Lua ==================================================// extern "C" LUALIB_API int luaopen_QLuaCallbacks(lua_State *L) { luaL_openlib(L, "QLuaCallbacks", ls_lib, 0); //Добавляет функцию в стек lua_pushcclosure(L, forLua_OnAllTrade, 0); //Регистрирует её как коллбэк на OnAllTrade lua_setglobal(L, "OnAllTrade"); return 0; } |
#include <windows.h> #include <string> //=== Необходимые для 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; } struct DateTime { int mcs; //Микросекунды int ms; //Миллисекунды int sec; //Секунды int min; //Минуты int hour; //Часы int day; //День int week_day; //Номер дня недели int month; //Месяц int year; //Год }; std::string getFieldValue(lua_State *L, const char *key) { std::string result; lua_pushstring(L, key); /* поместить ключ на стек */ lua_gettable(L, -2); /* получить значение */ result = lua_tostring(L, -1); lua_pop(L, 1); return result; } DateTime getDateTimeField(lua_State *L) { DateTime datetime; lua_pushstring(L, "datetime"); /* поместить ключ на стек */ lua_gettable(L, -2); /* получить таблицу datetime */ lua_pushstring(L, "mcs"); //Микросекунды lua_gettable(L, -2); datetime.mcs = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "ms"); //Миллисекунды lua_gettable(L, -2); datetime.ms = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "sec"); //Секунды lua_gettable(L, -2); datetime.sec = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "min"); //Минуты lua_gettable(L, -2); datetime.min = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "hour"); //Часы lua_gettable(L, -2); datetime.hour = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "day"); //День lua_gettable(L, -2); datetime.day = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "week_day"); //Номер дня недели lua_gettable(L, -2); datetime.week_day = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "month"); //Месяц lua_gettable(L, -2); datetime.month = lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "year"); //Год lua_gettable(L, -2); datetime.year = lua_tonumber(L, -1); lua_pop(L, 1); lua_pop(L, 1); return datetime; } //=== Реализация функций обратного вызова ====================================================================// static int forLua_OnAllTrade(lua_State *L) // { // Проверяет, является-ли первый элемент стека массивом (таблицей Lua) if (lua_istable(L, 1)) { std::string trade_num = getFieldValue(L, "trade_num"); // Номер сделки в торговой системе std::string flags = getFieldValue(L, "flags"); // Набор битовых флагов std::string price = getFieldValue(L, "price"); // Цена std::string qty = getFieldValue(L, "qty"); // Количество бумаг в последней сделке в лотах std::string value = getFieldValue(L, "value"); // Объем в денежных средствах std::string accruedint = getFieldValue(L, "accruedint"); // Накопленный купонный доход std::string yield = getFieldValue(L, "yield"); // Доходность std::string settlecode = getFieldValue(L, "settlecode"); // Код расчетов std::string reporate = getFieldValue(L, "reporate"); // Ставка РЕПО(%) std::string repovalue = getFieldValue(L, "repovalue"); // Сумма РЕПО std::string repo2value = getFieldValue(L, "repo2value"); // Объем выкупа РЕПО std::string repoterm = getFieldValue(L, "repoterm"); // Срок РЕПО в днях std::string sec_code = getFieldValue(L, "sec_code"); // Код бумаги заявки std::string class_code = getFieldValue(L, "class_code"); // Код класса DateTime datetime = getDateTimeField(L); // Дата и время std::string period = getFieldValue(L, "period"); // Период торговой сессии.Возможные значения : «0» – Открытие; «1» – Нормальный; «2» – Закрытие if (sec_code == "SBER") { std::string TradeInfo = "trade_num=" + trade_num + " " + "flags=" + flags + " " + "price=" + price + " " + "qty=" + qty + " " + "value=" + value + " " + "accruedint=" + accruedint + " " + "yield=" + yield + " " + "settlecode=" + settlecode + " " + "reporate=" + reporate + " " + "repovalue=" + repovalue + " " + "repo2value=" + repo2value + " " + "repoterm=" + repoterm + " " + "sec_code=" + sec_code + " " + "class_code=" + class_code + " " + "time=" + std::to_string(datetime.hour) + ":" + std::to_string(datetime.min) + ":" + std::to_string(datetime.sec) + "." + std::to_string(datetime.mcs) + " " + "trade_num=" + trade_num + " " + "period=" + period; //Выводит сообщение в терминале с информацией по сделке lua_getglobal(L, "message"); lua_pushfstring(L, TradeInfo.c_str()); lua_pcall(L, 1, 0, 0); } } return 0; } //=== Регистрация реализованных в dll функций, чтобы они стали "видимы" для Lua ================================// static struct luaL_reg ls_lib[] = { { NULL, NULL } }; //=== Регистрация названия библиотеки, видимого в скрипте Lua ==================================================// extern "C" LUALIB_API int luaopen_QLuaCallbacks(lua_State *L) { luaL_openlib(L, "QLuaCallbacks", ls_lib, 0); //Добавляет функцию в стек lua_pushcclosure(L, forLua_OnAllTrade, 0); //Регистрирует её как коллбэк на OnAllTrade lua_setglobal(L, "OnAllTrade"); return 0; }
Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!