Rinat_Namazov |
Дата: Четверг, 04.10.2018, 16:33 | Сообщение # 1
|
Боец
Сообщений: 122
Статус: Offline
|
AHK-LUA-API AHK-LUA-API API для взаимодействия LUA и AHK. API состоит из файла AHK-LUA-API.ahk, для работы требуется lua51.dll. Для подключения библиотеки нужно вписать в начало скрипта следующий код:
Код #include AHK-LUA-API.ahk
Перед тем как вызывать функции нужно подгрузить lua51.dll в процесс ахк.
Код DllCall("kernel32.dll\LoadLibrary", "Str", A_ScriptDir "\lua51.dll") Примеры: Вызов AHK функции из Lua:
Код L := luaL_newstate() lua_register(L, "MsgBox", "LUAFUNC_MsgBox") lua_register(L, "Test", "LUAFUNC_Test")
code = ( sum = Test(228, 1337, 666) MsgBox("sum = " .. sum) )
luaL_doString(L, code) lua_close(L)
LUAFUNC_MsgBox(L) { MsgBox, % lua_tostring(L, 1) return 0 }
LUAFUNC_Test(L) { sum := 0 n := lua_gettop(L) loop % n sum += lua_tonumber(L, A_Index) lua_pushnumber(L, sum) return 1 }
Вызов Lua функции из AHK:
Код L := luaL_newstate()
code = ( function add(x, y) return x + y end )
luaL_doString(L, code) MsgBox, % LUAFUNC_add(L, 5, 13) lua_close(L)
LUAFUNC_add(L, x, y) { lua_getglobal(L, "add") lua_pushnumber(L, x) lua_pushnumber(L, y) lua_call(L, 2, 1) sum := lua_tointeger(L, -1) lua_pop(L, 1) return sum }
Чтение Lua переменных:
Код L := luaL_newstate()
code = ( var = "String" )
luaL_doString(L, code)
lua_getglobal(L, "var") MsgBox, % lua_tostring(L, -1)
lua_close(L)
Активация функции на клавишу, через AHK:
Код L := luaL_newstate()
lua_register(L, "MsgBox", "LUAFUNC_MsgBox") lua_register(L, "Hotkey", "LUAFUNC_Hotkey")
code = ( Hotkey("!1", "Show", "On") function Show(ThisHotKey) MsgBox("ThisHotKey = " .. ThisHotKey) end )
luaL_doString(L, code)
LUAFUNC_MsgBox(L) { MsgBox, % lua_tostring(L, 1) return 0 }
LUAFUNC_Hotkey(L) { static HotKeyCount := 0, ARGS := {} ARGS.Push({L: L, ARG1: lua_tostring(L, 1), ARG2: lua_tostring(L, 2), ARG3: lua_tostring(L, 3)}) HotKeyCount++ Hotkey, % ARGS[HotKeyCount]["ARG1"], LuaHotKey, % ARGS[HotKeyCount]["ARG3"] lua_pushnumber(L, ErrorLevel) return 1 LuaHotKey: for k, v in ARGS { if (A_ThisHotkey == v["ARG1"]) { lua_getglobal(v["L"], v["ARG2"]) lua_pushstring(v["L"], A_ThisHotkey) lua_call(v["L"], 1, 0) } } return }
Экспорты луа апи генерируются автоматический: То что добавлено вручную можно найти на гитхабе.
Код GetType(type, isRetVal := false) { types := { "lua_State": "Ptr" , "int": "Int" , "size_t": "Int" , "const char": "Str" , "lua_Integer": "Int" , "lua_Number": "Double" } if (isRetVal && type == "void") return "" if (types[type] != "") return (isRetVal ? " " : "") types[type] return (isRetVal ? " " : "") "UInt" ; const luaL_Reg, luaL_Buffer, lua_Alloc, lua_CFunction, const lua_Debug, lua_Debug, lua_Hook, lua_Reader, lua_Writer } FuncList := ["LUAJIT_VERSION_SYM"]
Loop, LuaJIT-master\src\*.c ; Проходимся по всем файлам с расширением ".c" исходника LUA-JIT. { A_FileText := "", fpos := 1 ; Позиция с которого начинается поиск по шаблону. Loop, Read, %A_LoopFileFullPath% ; Читаем построчно файл. { TrimLine := Trim(A_LoopReadLine) ; Убираем лишние символы (\n|\r|\s|\t). if (TrimLine != "") ; Если строка не пустая. A_FileText .= TrimLine ; Добавляем строку без переноса. } while (npos := RegExMatch(A_FileText, "mUS)(LUALIB_API|LUA_API)\s(?<Type>[a-zA-Z0-9_\s]+)\s(?<IsPtrOrAddrOrDefault>[*&]{0,1})(?<Name>[a-zA-Z0-9_]+)\((?<Params>.*)\)", Func_, fpos)) ; Поиск функций. { fpos := npos + strlen(Func_) ; Прибавляем к позиции длину вхождения. IsContinue := false for k, v in FuncList ; Поиск функции, вдруг она уже найдена. { if (Func_Name == v) IsContinue := true ; Функция найдена. } if (IsContinue) ; Если функция уже найдена. continue ; Пропускаем. AhkFuncParams := "", DllCallParams := "" ; Будущие аргументы. if (Func_Params != "void") ; Если функция имеет аргументы. { Loop, Parse, % Func_Params, `, ; Проходимся по аргументам функции. { RegExMatch(Trim(A_LoopField), "S)(?<Type>[a-zA-Z0-9_\s]+)\s(?<IsPtrOrAddrOrDefault>[*&]{0,2})(?<Name>[a-zA-Z0-9_]+)", Params_) ; Делим аргумент на тип и название. if (Params_Type == "va_list" || A_LoopField == " ...") ; Пропускаем, ведь ахк само умеет форматировать. continue if (Params_Name == "l") ; Так как AHK не регистрозависимый язык, нужно заменить. Params_Name := "l2" AhkFuncParams .= (A_Index == 1 ? "" : ", ") (Params_IsPtrOrAddrOrDefault == "*" ? "ByRef " : "") Params_Name ; Аргументы в ахк функцию. DllCallParams .= (A_Index == 1 ? "" : ", ") """" GetType(Params_Type) """, " Params_Name ; Аргументы в С функцию. } } FuncList.Push(Func_Name) ; Добавляем функцию в список. result .= "`n`n" Func_Name "(" AhkFuncParams ")`n{`n`treturn DllCall(""lua51.dll\" Func_Name """" (DllCallParams == "" ? "" : ", " DllCallParams) ", ""CDecl" GetType(Func_Type, true) """)`n}" ; Формируем код. } }
FileDelete, AHK-LUA-API.ahk FileAppend, %result%, AHK-LUA-API.ahk
Скачать
|
|
|
|