AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

AHK + LUA Interop (stdlib), proof of concept
Goto page 1, 2  Next
 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Thrawn



Joined: 12 May 2008
Posts: 30
Location: Germany

PostPosted: Tue May 12, 2009 6:33 pm    Post subject: AHK + LUA Interop (stdlib), proof of concept Reply with quote

LibLua
Quote:
What is Lua?
Lua is a powerful, fast, lightweight, embeddable scripting language.

Lua combines simple procedural syntax with powerful data description constructs based on associative arrays and extensible semantics. Lua is dynamically typed, runs by interpreting bytecode for a register-based virtual machine, and has automatic memory management with incremental garbage collection, making it ideal for configuration, scripting, and rapid prototyping.


I've just started wrapping LUA for AHK. So far i've implemented the needed functions to:
- call ahk-functions from lua
- call lua-functions from ahk
- read lua-variables with ahk
- run a lua-script from within ahk

For now this is merely a proof of concept, but if you want to try it
- get the required libs from here (lua5.1.dll, lua51.dll)
- and examples + lua-ahk stdlib from here (zip)

Example 1.1: Calling an ahk-command from lua
Code:
hDll := lua_loadDll("lua51.dll")
l := luaL_newstate()
luaL_openlibs(l)

AverageAddress := RegisterCallback("average","C")

lua_register(l, "average", AverageAddress)

code =
(
   -- Start
   file = io.open ("example_callAhkFromLua.txt","w")
   avg, sum = average(10, 20, 30, 40, 50)
   file:write("The average is ", avg)
   file:write("\nThe sum is ", sum)

   file:write("\n")

   avg, sum = average(1, 2, 3, 4, 5)
   file:write("\nThe average is ", avg)
   file:write("\nThe sum is ", sum)

   file:close()
   -- End
)

luaL_doString(l, code)

lua_close(l)
lua_UnloadDll(hDll)

return

average(L)
{
   ; get number of arguments
   n := lua_gettop(L)
   sum := 0

   ; loop through each argument
   loop, %n%
   {
     ; total the arguments
     sum += lua_tonumber(L, A_Index)
   }

   ; push the average
   lua_pushnumber(L, sum / n)

   ; push the sum
   lua_pushnumber(L, sum)

   ; return the number of results
   return 2
}


Example 1.2: Calling an ahk-command from lua
Code:
#include lua_ahkfunctions.ahk

hDll := lua_loadDll("lua51.dll")
l := luaL_newstate()

luaL_openlibs(l)
lua_registerAhkFunction(l)

code =
(
   -- Start
   step = 0
   while (step <= 100) do
      Tooltip(step)
      Sleep(20)
      step = step + 1
   end
   Tooltip("")
   Msgbox("Done!")

   Gui("Add", "Text","x5 y5", "Please enter your name:")
   Gui("Add", "Edit","vNameEdit")
   Gui("Add", "Button","gOnExit","Exit")
   Gui("Show")
   -- End
)

luaL_dostring(l, code)

return

OnExit:
   lua_close(l)
   lua_UnloadDll(hDll)
   ExitApp


Example 2: Calling an lua-function from ahk
Quote:
example_callLuaFromAhk.ahk
Code:
hDll := lua_loadDll("lua51.dll")
l := lua_newstate()
lua_openlibs(l)

lua_dofile(l, "example_callLuaFromAhk.lua")

sum := luaadd(10,15)

msgbox, The sum is %sum%

lua_close(l)

lua_UnloadDll(hDll)


return

luaadd(x,y)
{
   Global l

   ; the function name
   lua_getglobal(L, "add")

   ; the first argument
   lua_pushnumber(L, x)

   ; the second argument
   lua_pushnumber(L, y)

   ; call the function with 2 arguments, return 1 result
   lua_call(L, 2, 1)

   ; get the result
   sum := lua_tointeger(L, -1)

   lua_pop(L, 1)

   return % sum
}

example_callLuaFromAhk.lua
Code:
function add ( x, y )
   return x + y
end

Example 3: Read a variable from lua
Quote:
example_getVarFromLuaToAhk.ahk
Code:
hDll := lua_loadDll("lua51.dll")

l := lua_newstate()

if(lua_loadfile(L,"example_getVarFromLuaToC.lua") || lua_pcall(L,0,0,0))
   msgbox % "Error failed to load " lua_tostring(L,-1)
else
{
   lua_getglobal(L,"screenWidth")
   screenWidth := lua_tonumber(L,-1)
   out := "Screen Width := " screenWidth "`n"

   lua_getglobal(L,"appName")
   appName := lua_tostring(l, -1)
   out := out "Screen Name := " appName

   msgbox % out
}

lua_close(L)
lua_UnloadDll(hDll)

example_getVarFromLuaToAhk.lua
Code:
appName = "Firefox"
screenWidth = 400


Example 4: creating a hotkey in lua
Code:
#include lua_ahkfunctions.ahk

hDll := lua_loadDll("lua51.dll")
l := luaL_newstate()

luaL_openlibs(l)
lua_registerAhkFunction(l)

code =
(
   -- Start
   Hotkey("#3","boxy")
   Hotkey("#6","endme")

   function endme()
       Gosub("OnExit")
   end

   function boxy ()
       Msgbox("this lua-function has been called by hotkey")
   end
   -- End
)
luaL_dostring(l, code)

return


OnExit:
   lua_close(l)
   lua_UnloadDll(hDll)
   ExitApp


lua.ahk
Code:
lua_LoadDLL(dll)
{
   return, DllCall("LoadLibrary", "str", dll)
}

lua_UnloadDLL(hDll)
{
   DllCall("FreeLibrary", "UInt", hDll)
}

lua_atPanic(ByRef l, panicf)
{
   Return, DllCall("lua51\lua_atPanic", "UInt", L, "UInt", panicF, "Cdecl")
}

lua_call(ByRef l, nargs, nresults)
{
   Return, DllCall("lua51\lua_pcall", "UInt", l, "Int", nargs, "Int", nresults, "Cdecl")
}

lua_checkstack(ByRef l, extra)
{
   Return, DllCall("lua51\lua_checkstack", "UInt", l, "Int", extra, "Cdecl Int")
}

lua_close(ByRef l)
{
   Return, DllCall("lua51\lua_close", "UInt", l, "Cdecl")
}

lua_concat(ByRef l, extra)
{
   Return, DllCall("lua51\lua_concat", "UInt", l, "Int", extra, "Cdecl")
}

lua_cpcall(ByRef l, func, ByRef ud)
{
   Return, DllCall("lua51\lua_cpcall", "UInt", l, "UInt", func, "UInt", ud, "Cdecl Int")
}

lua_createtable(ByRef l, narr, nrec)
{
   Return, DllCall("lua51\lua_createtable", "UInt", l, "Int", narr, "Int", nrec, "Cdecl")
}

lua_dump(ByRef l, writer, ByRef data)
{
   Return, DllCall("lua51\lua_dump", "UInt", l, "UInt", writer, "UInt", data, "Cdecl Int")
}

lua_equal(ByRef l, index1, index2)
{
   Return, DllCall("lua51\lua_equal", "UInt", l, "Int", index1, "Int", index2, "Cdecl Int")
}

lua_error(ByRef l)
{
   Return, DllCall("lua51\lua_error", "UInt", l, "Cdecl Int")
}

lua_gc(ByRef l, what, data)
{
   Return, DllCall("lua51\lua_gc", "UInt", l, "Int", what, "Int", data, "Cdecl Int")
}

;lua_getallofc(lua_State *L, void **ud)
; Returns the memory-allocation function of a given state.
; If ud is not NULL, Lua stores in *ud the opaque pointer passed to lua_newstate.

lua_getfenv(ByRef l, index)
{
   Return, DllCall("lua51\lua_getfenv", "UInt", l, "Int", index, "Cdecl")
}

lua_getfield(ByRef L, index, name)
{
   Return, DllCall("lua51\lua_getfield", "UInt", L, "Int", index, "Str", name, "Cdecl")
}

lua_getglobal(ByRef L, name)
{
   ;Return, DllCall("lua51\lua_getfield", "UInt", L, "Int", -10002, "Str", name, "Cdecl")
   Return, lua_getfield(L, -10002, name)
}

lua_getmetatable(ByRef L, index)
{
   Return, DllCall("lua51\lua_getmetatable", "UInt", L, "Int", index, "Cdecl Int")
}

lua_gettable(ByRef L, index)
{
   Return, DllCall("lua51\lua_gettable", "UInt", L, "Int", index, "Cdecl")
}

lua_gettop(ByRef l)
{
   Return, DllCall("lua51\lua_gettop", "UInt", l, "Cdecl Int")
}

lua_insert(ByRef l, index)
{
   Return, DllCall("lua51\lua_insert", "UInt", l, "Int", index, "Cdecl")
}

lua_isboolean(ByRef l, index)
{
   Return, DllCall("lua51\lua_isboolean", "UInt", L, "Int", index, "Cdecl Int")
}

lua_iscfunction(ByRef l, index)
{
   Return, DllCall("lua51\lua_iscfunction", "UInt", L, "Int", index, "Cdecl Int")
}

lua_isfunction(ByRef l, index)
{
   Return, DllCall("lua51\lua_isfunction", "UInt", L, "Int", index, "Cdecl Int")
}

lua_islightuserdata(ByRef l, index)
{
   Return, DllCall("lua51\lua_islightuserdata", "UInt", L, "Int", index, "Cdecl Int")
}

lua_isnil(ByRef l, index)
{
   Return, DllCall("lua51\lua_isnil", "UInt", L, "Int", index, "Cdecl Int")
}

lua_isnone(ByRef l, index)
{
   Return, DllCall("lua51\lua_isnone", "UInt", L, "Int", index, "Cdecl Int")
}

lua_isnoneornil(ByRef l, index)
{
   Return, DllCall("lua51\lua_isnoneornil", "UInt", L, "Int", index, "Cdecl Int")
}

lua_isnumber(ByRef l, index)
{
   Return, DllCall("lua51\lua_isnumber", "UInt", L, "Int", index, "Cdecl Int")
}

lua_isstring(ByRef l, index)
{
   Return, DllCall("lua51\lua_isstring", "UInt", L, "Int", index, "Cdecl Int")
}

lua_istable(ByRef l, index)
{
   Return, DllCall("lua51\lua_istable", "UInt", L, "Int", index, "Cdecl Int")
}

lua_isthread(ByRef l, index)
{
   Return, DllCall("lua51\lua_isthread", "UInt", L, "Int", index, "Cdecl Int")
}

lua_isuserdata(ByRef l, index)
{
   Return, DllCall("lua51\lua_isuserdata", "UInt", L, "Int", index, "Cdecl Int")
}

lua_lessthan(ByRef l, index)
{
   Return, DllCall("lua51\lua_lessthan", "UInt", L, "Int", index, "Cdecl Int")
}

lua_load(ByRef l, reader, ByRef data, ByRef chunkname)
{
   Return, DllCall("lua51\lua_load", "UInt", L, "UInt", reader, "UInt", data, "UInt", chunkname, "Cdecl Int")
}

lua_newstate(f, ByRef ud)
{
   Return, DllCall("lua51\lua_newstate", "UInt", f, "UInt", ud, "Cdecl UInt")
}

lua_newtable(ByRef l)
{
   ;Return, DllCall("lua51\lua_newtable", "UInt", l, "Cdecl")
   Return, lua_createTable(l, 0, 0)
}

lua_newthread(ByRef l)
{
   Return, DllCall("lua51\lua_newthread", "UInt", l, "Cdecl UInt")
}

;void *lua_newuserdata (lua_State *L, size_t size)
; This function allocates a new block of memory with the given size, pushes onto the
; stack a new full userdata with the block address, and returns this address.

lua_next(ByRef l, index)
{
   Return, DllCall("lua51\lua_next", "UInt", L, "Int", index, "Cdecl Int")
}

/*
;--------------------------------------------
;--- A typical traversal looks like this: ---
;--------------------------------------------
   ;table is in the stack at index 't'
   ;first key
   lua_pushnil(L)
   while (lua_next(L, t) != 0)
   {
    ;uses 'key' (at index -2) and 'value' (at index -1)
    msgbox % lua_typename(L, lua_type(L, -2)) " - " lua_typename(L, lua_type(L, -1))

    ;removes 'value'; keeps 'key' for next iteration
    lua_pop(L, 1);
   }
*/


lua_objlen(ByRef l, index)
{
   Return, DllCall("lua51\lua_objlen", "UInt", L, "Int", index, "Cdecl Int")
}

lua_pcall(ByRef l, nargs, nresults, errfunc)
{
   Return, DllCall("lua51\lua_pcall", "UInt", l, "Int", nargs, "Int", nresults, "UInt", errfunc, "Cdecl")
}

lua_pop(ByRef l, no)
{
   Return, DllCall("lua51\lua_pop", "UInt", l, "Int", no, "Cdecl")
}

lua_pushboolean(ByRef l, bool)
{
   Return, DllCall("lua51\lua_pushboolean", "UInt", l, "Int", bool, "Cdecl")
}

lua_pushcclosure(ByRef L, funcAddr, n)
{
   Return, DllCall("lua51\lua_pushcclosure", "UInt", L, "UInt", funcAddr, "Int", n, "Cdecl")
}

lua_pushcfunction(ByRef L, funcAddr)
{
   Return, DllCall("lua51\lua_pushcclosure", "UInt", L, "UInt", funcAddr, "Int", 0, "Cdecl")
   ;Return, lua_pushcclosure(L, funcAdd, 0)
}

;const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
; Pushes onto the stack a formatted string and returns a pointer to this string.
; It is similar to the C function sprintf. also: lua_pushvfstring()

lua_pushinteger(ByRef l, int)
{
   Return, DllCall("lua51\lua_pushinteger", "UInt", l, "Int", int, "Cdecl")
}

lua_pushlightuserdata(ByRef l, ByRef p)
{
   Return, DllCall("lua51\lua_pushlightuserdata", "UInt", l, "UInt", p, "Cdecl")
}

lua_pushliteral(ByRef l, ByRef str)
{
   Return, DllCall("lua51\lua_pushliteral", "UInt", l, "UInt", str, "Cdecl")
}

lua_pushlstring(ByRef l, ByRef str, len)
{
   Return, DllCall("lua51\lua_pushlstring", "UInt", l, "UInt", str, "Int", len, "Cdecl")
}

lua_pushnil(ByRef l)
{
   Return, DllCall("lua51\lua_pushnil", "UInt", l, "Cdecl")
}

lua_pushnumber(ByRef l, no)
{
   Return, DllCall("lua51\lua_pushnumber", "UInt", l, "Double", no, "Cdecl")
}

lua_pushstring(ByRef l, ByRef str)
{
   Return, DllCall("lua51\lua_pushstring", "UInt", l, "Str", str, "Cdecl")
}

lua_pushthread(ByRef l)
{
   Return, DllCall("lua51\lua_pushthread", "UInt", l, "Cdecl")
}

lua_pushvalue(ByRef l, index)
{
   Return, DllCall("lua51\lua_pushvalue", "UInt", l, "Int", index, "Cdecl")
}

lua_rawequal(ByRef l, index1, index2)
{
   Return, DllCall("lua51\lua_rawequal", "UInt", l, "Int", index1, "Int", index2, "Cdecl Int")
}

lua_rawget(ByRef l, index)
{
   Return, DllCall("lua51\lua_rawget", "UInt", l, "Int", index, "Cdecl")
}

lua_rawgeti(ByRef l, index, n)
{
   Return, DllCall("lua51\lua_rawgeti", "UInt", l, "Int", index, "Int", n, "Cdecl")
}

lua_rawset(ByRef l, index)
{
   Return, DllCall("lua51\lua_rawset", "UInt", l, "Int", index, "Cdecl")
}

lua_rawseti(ByRef l, index, n)
{
   Return, DllCall("lua51\lua_rawseti", "UInt", l, "Int", index, "Int", n, "Cdecl")
}

lua_register(ByRef l, name, funcAddr)
{
   ;Return, DllCall("lua51\lua_register", "UInt", l, "Str", name, "UInt", funcAddr, "Cdecl")
   lua_pushcfunction(l, funcAddr)
   lua_setglobal(l, name)
}

lua_remove(ByRef l, index)
{
   Return, DllCall("lua51\lua_remove", "UInt", l, "Int", index, "Cdecl")
}

lua_replace(ByRef l, index)
{
   Return, DllCall("lua51\lua_replace", "UInt", l, "Int", index, "Cdecl")
}

lua_resume(ByRef l, narg)
{
   Return, DllCall("lua51\lua_resume", "UInt", l, "Int", narg, "Cdecl Int")
}

lua_setallocf(ByRef l, f, ByRef ud)
{
   Return, DllCall("lua51\lua_setallocf", "UInt", l, "UInt", f, "UInt", ud, "Cdecl")
}

lua_setfenv(ByRef l, index)
{
   Return, DllCall("lua51\lua_setfenv", "UInt", l, "Int", index, "Cdecl Int")
}

lua_setfield(ByRef L, index, name)
{
   Return, DllCall("lua51\lua_setfield", "UInt", L, "Int", index, "Str", name, "Cdecl")
}

lua_setglobal(ByRef L, name)
{
   ;Return, DllCall("lua51\lua_setfield", "UInt", L, "Int", -10002, "Str", name, "Cdecl")
   Return, lua_setfield(L, -10002, name)
}

lua_setmetatable(ByRef L, index)
{
   Return, DllCall("lua51\lua_setmetatable", "UInt", L, "Int", index, "Cdecl Int")
}

lua_settable(ByRef L, index)
{
   Return, DllCall("lua51\lua_settable", "UInt", L, "Int", index, "Cdecl")
}

lua_settop(ByRef l, index)
{
   Return, DllCall("lua51\lua_settop", "UInt", l, "Int", index, "Cdecl")
}

lua_status(ByRef l)
{
   Return, DllCall("lua51\lua_status", "UInt", l, "Cdecl")
}

lua_toboolean(ByRef l, no)
{
   Return, DllCall("lua51\lua_toboolean", "UInt", l, "Int", no, "Cdecl Int")
}

lua_tocfunction(ByRef l, no)
{
   Return, DllCall("lua51\lua_tocfunction", "UInt", l, "Int", no, "Cdecl UInt")
}

lua_tointeger(ByRef l, no)
{
   Return, DllCall("lua51\lua_tointeger", "UInt", l, "Int", no, "Cdecl Int")
}

lua_tolstring(ByRef l, no, size)
{
   Return, DllCall("lua51\lua_tolstring", "UInt", l, "Int", no, "Int", size, "Cdecl Str")
}

lua_tonumber(ByRef l, no)
{
   Return, DllCall("lua51\lua_tonumber", "UInt", l, "Int", no, "Cdecl Double")
}

lua_topointer(ByRef l, no)
{
   Return, DllCall("lua51\lua_topointer", "UInt", l, "Int", no, "Cdecl UInt")
}

lua_tostring(ByRef l, no)
{
   ;Return, DllCall("lua51\lua_tostring", "UInt", l, "Int", no, "Cdecl Str")
   Return, lua_tolstring(l, no, 0)
}

lua_tothread(ByRef l, no)
{
   Return, DllCall("lua51\lua_tothread", "UInt", l, "Int", no, "Cdecl UInt")
}

lua_touserdata(ByRef l, no)
{
   Return, DllCall("lua51\lua_touserdata", "UInt", l, "Int", no, "Cdecl UInt")
}

lua_type(ByRef l, no)
{
   Return, DllCall("lua51\lua_type", "UInt", l, "Int", no, "Cdecl Int")
}

lua_typename(ByRef l, tp)
{
   Return, DllCall("lua51\lua_typename", "UInt", l, "Int", tp, "Cdecl Str")
}

lua_xmove(ByRef from, ByRef to, n)
{
   Return, DllCall("lua51\lua_xmove", "UInt", from, "UInt", to, "Int", n, "Cdecl")
}

lua_yield(ByRef l, nresults)
{
   Return, DllCall("lua51\lua_yield", "UInt", l, "Int", nresults, "Cdecl Int")
}



;---------------------------------------------
; Load the standard Lua libraries
;---------------------------------------------
luaopen_base(ByRef l)
{
   Return, DllCall("lua51\luaopen_base", "UInt", l, "Cdecl")
}

luaopen_package(ByRef l)
{
   Return, DllCall("lua51\luaopen_package", "UInt", l, "Cdecl")
}

luaopen_string(ByRef l)
{
   Return, DllCall("lua51\luaopen_string", "UInt", l, "Cdecl")
}

luaopen_table(ByRef l)
{
   Return, DllCall("lua51\luaopen_table", "UInt", l, "Cdecl")
}

luaopen_math(ByRef l)
{
   Return, DllCall("lua51\luaopen_math", "UInt", l, "Cdecl")
}

luaopen_io(ByRef l)
{
   Return, DllCall("lua51\luaopen_io", "UInt", l, "Cdecl")
}

luaopen_os(ByRef l)
{
   Return, DllCall("lua51\luaopen_os", "UInt", l, "Cdecl")
}

luaopen_debug(ByRef l)
{
   Return, DllCall("lua51\luaopen_debug", "UInt", l, "Cdecl")
}

;---------------------------------------------
;luaL
;---------------------------------------------
luaL_buffinit(ByRef l, ByRef Buffer)
{
   Return, DllCall("lua51\luaL_buffinit", "UInt", l, "UInt", Buffer, "Cdecl")
}

luaL_callmeta(ByRef l, obj, ByRef e)
{
   Return, DllCall("lua51\luaL_callmeta", "UInt", l, "Int", obj, "Str", e, "Cdecl Int")
}

luaL_checkany(ByRef l, narg)
{
   Return, DllCall("lua51\luaL_checkany", "UInt", l, "Int", narg, "Cdecl")
}

luaL_checkint(ByRef l, no)
{
   Return, DllCall("lua51\luaL_checkint", "UInt", l, "Int", no, "Cdecl Int")
}

luaL_checkinteger(ByRef l, no)
{
   Return, DllCall("lua51\luaL_checkinteger", "UInt", l, "Int", no, "Cdecl Int")
}

luaL_checklong(ByRef l, no)
{
   Return, DllCall("lua51\luaL_checklong", "UInt", l, "Int", no, "Cdecl Int")
}

luaL_checklstring(ByRef l, no, ByRef len)
{
   Return, DllCall("lua51\luaL_checklstring", "UInt", l, "Int", no, "UInt", len, "Cdecl Str")
}

luaL_checknumber(ByRef l, no)
{
   Return, DllCall("lua51\luaL_checknumber", "UInt", l, "Int", no, "Cdecl Int")
}

luaL_checkoption(ByRef l, no, ByRef def, ByRef lst)
{
   Return, DllCall("lua51\luaL_checkoption", "UInt", l, "Int", no, "UInt", def, "UInt", lst, "Cdecl Int")
}

luaL_checkstack(ByRef l, no, ByRef msg)
{
   Return, DllCall("lua51\luaL_checkstack", "UInt", l, "Int", no, "Str", msg, "Cdecl")
}

luaL_checkstring(ByRef l, narg)
{
   Return, DllCall("lua51\luaL_checkstring", "UInt", l, "Int", narg, "Cdecl")
}

luaL_checktype(ByRef l, no, t)
{
   Return, DllCall("lua51\luaL_checktype", "UInt", l, "Int", no, "Int", t, "Cdecl")
}

luaL_checkudata(ByRef l, no, ByRef tname)
{
   Return, DllCall("lua51\luaL_checkudata", "UInt", l, "Int", no, "Str", tname, "Cdecl")
}

luaL_dofile(ByRef l, file)
{
   ;Return, DllCall("lua51\luaL_dofile", "UInt", l, "Str", file, "Cdecl Int")
   luaL_loadfile(l, file)
   Return % lua_pCall(l, 0, -1, 0)
}

luaL_dostring(ByRef l, ByRef str)
{
   ;Return, DllCall("lua51\luaL_dostring", "UInt", l, "Str", str, "Cdecl Int")
   luaL_loadstring(l, str)
   Return % lua_pCall(l, 0, -1, 0)
}

luaL_error(ByRef l, ByRef str)
{
   Return, DllCall("lua51\luaL_error", "UInt", l, "Str", str, "Cdecl Int")
}

luaL_getmetafield(ByRef l, no, ByRef e)
{
   Return, DllCall("lua51\luaL_getmetafield", "UInt", l, "Int", no, "Str", e, "Cdecl Int")
}

luaL_getmetatable(ByRef l, ByRef tname)
{
   Return, DllCall("lua51\luaL_getmetatable", "UInt", l, "Str", tname, "Cdecl")
}

luaL_gsub(ByRef l, ByRef s, ByRef p, ByRef r)
{
   Return, DllCall("lua51\luaL_gsub", "UInt", l, "UInt", s, "UInt", p, "UInt", r, "Cdecl Str")
}

luaL_loadbuffer(ByRef l, ByRef buff, sz, ByRef name)
{
   Return, DllCall("lua51\luaL_loadbuffer", "UInt", l, "UInt", buff, "Int", sz, "Str", name, "Cdecl Int")
}

luaL_loadfile(ByRef l, file)
{
   Return, DllCall("lua51\luaL_loadfile", "UInt", l, "Str", file, "Cdecl Int")
}

luaL_loadstring(ByRef l, ByRef s)
{
   Return, DllCall("lua51\luaL_loadstring", "UInt", l, "Str", s, "Cdecl Int")
}

luaL_newmetatable(ByRef l, ByRef tname)
{
   Return, DllCall("lua51\luaL_newmetatable", "UInt", l, "Str", tname, "Cdecl Int")
}

luaL_newstate()
{
   Return, DllCall("lua51\luaL_newstate", "Cdecl")
}

luaL_openlibs(ByRef l)
{
   Return, DllCall("lua51\luaL_openlibs", "UInt", l, "Cdecl")
}

;int luaL_optint (lua_State *L, int narg, int d);
;lua_Integer luaL_optinteger (lua_State *L, int narg, lua_Integer d);
;long luaL_optlong (lua_State *L, int narg, long d);
;const char *luaL_optlstring (lua_State *L, int narg, const char *d, size_t *l);
;lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number d);
;const char *luaL_optstring (lua_State *L, int narg, const char *d);
;char *luaL_prepbuffer (luaL_Buffer *B);
;void luaL_pushresult (luaL_Buffer *B);
;int luaL_ref (lua_State *L, int t);
;void luaL_register (lua_State *L, const char *libname, const luaL_Reg *l)
;const char *luaL_typename (lua_State *L, int index);
;int luaL_typerror (lua_State *L, int narg, const char *tname);
;void luaL_unref (lua_State *L, int t, int ref);
;void luaL_where (lua_State *L, int lvl);


lua_ahkfunctions.ahk, to big to post. read here.


Last edited by Thrawn on Thu May 14, 2009 4:13 pm; edited 5 times in total
Back to top
View user's profile Send private message
harry.liang



Joined: 10 May 2009
Posts: 3

PostPosted: Wed May 13, 2009 3:08 am    Post subject: Re: AHK + LUA Interop (stdlib), proof of concept Reply with quote

It's great! what if someone can do the same thing with python! I am dreaming of that for a long time!
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 7282
Location: Australia

PostPosted: Wed May 13, 2009 10:39 am    Post subject: Re: AHK + LUA Interop (stdlib), proof of concept Reply with quote

Impressive!

A few functions I found useful during random experimentation (which don't seem to be in the current Lua.ahk):
Code:
lua_pushstring(ByRef l, s)
{
    Return, DllCall("lua51\lua_pushstring", "UInt", l, "UInt", &s, "Cdecl")
}

lua_loadstring(ByRef l, s)
{
    Return, DllCall("lua51\luaL_loadstring", "UInt", l, "UInt", &s, "Cdecl")
}

; Typically more useful to AutoHotkey scripts than lua_type, I suppose.
lua_typename(ByRef l, no)
{
     Return, DllCall("lua51\lua_typename", "UInt", l, "Int", lua_type(l, no), "Cdecl Str")
}

"Cdecl" should be used with any functions in lua51.dll which have parameters, otherwise ErrorLevel is set to An. (It should be safe as is due to the design of DllCall, but the non-zero ErrorLevels could be misleading.)

Off-topic: Hosting Python probably wouldn't be difficult with a bit of DllCall experience. It's covered in the Python documentation.
Back to top
View user's profile Send private message Visit poster's website
hughman



Joined: 11 Feb 2007
Posts: 166

PostPosted: Wed May 13, 2009 12:15 pm    Post subject: Reply with quote

Wow~~~

Lua is my favorite scripting language. I like lua's succinct syntax and flexible table.

If ahk can realize table natively, it'll be very very very much wonderful.
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 4511
Location: Belgrade

PostPosted: Wed May 13, 2009 1:01 pm    Post subject: Reply with quote

Thx for the interop. One of the good things about this system is that you can actually experiment with Lua C Binding without compiling it.

Lexikos wrote:
A few functions I found useful during random experimentation (which don't seem to be in the current Lua.ahk):

You can see about the entire API here, or if you prefer it in dotNet, here
_________________
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 7282
Location: Australia

PostPosted: Wed May 13, 2009 1:39 pm    Post subject: Reply with quote

majkinetor wrote:
You can see about the entire API here, or if you prefer it in dotNet, here
Thanks. I had been using this, turned up by a quick Google.
Back to top
View user's profile Send private message Visit poster's website
Thrawn



Joined: 12 May 2008
Posts: 30
Location: Germany

PostPosted: Wed May 13, 2009 2:39 pm    Post subject: Reply with quote

I'm using this and this as reference.
I'm planning on implementing all functions exposed by the api - most importantly luaL_dostring().
Currently I'm binding all ahk commands to lua:
Code:
-- Start
Msgbox(FileGetSize(FileSelectFile()))
-- End
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 4511
Location: Belgrade

PostPosted: Wed May 13, 2009 2:43 pm    Post subject: Reply with quote

I am more interested in doing oposite thing. Implementing as Lua modules automation things that exist in AHK - Window manipulation for start, then hotkeys/strings...
_________________
Back to top
View user's profile Send private message
Thrawn



Joined: 12 May 2008
Posts: 30
Location: Germany

PostPosted: Wed May 13, 2009 6:12 pm    Post subject: Reply with quote

I've updated the first post and the zip file.
The library is almost complete; missing C-Functions in lua.ahk:
Code:
;int luaL_optint (lua_State *L, int narg, int d);
;lua_Integer luaL_optinteger (lua_State *L, int narg, lua_Integer d);
;long luaL_optlong (lua_State *L, int narg, long d);
;const char *luaL_optlstring (lua_State *L, int narg, const char *d, size_t *l);
;lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number d);
;const char *luaL_optstring (lua_State *L, int narg, const char *d);
;char *luaL_prepbuffer (luaL_Buffer *B);
;void luaL_pushresult (luaL_Buffer *B);
;int luaL_ref (lua_State *L, int t);
;void luaL_register (lua_State *L, const char *libname, const luaL_Reg *l)
;const char *luaL_typename (lua_State *L, int index);
;int luaL_typerror (lua_State *L, int narg, const char *tname);
;void luaL_unref (lua_State *L, int t, int ref);
;void luaL_where (lua_State *L, int lvl);
;const char *lua_pushfstring (lua_State *L, const char *fmt, ...); + lua_pushvfstring()
;void *lua_newuserdata (lua_State *L, size_t size)
;lua_getallofc(lua_State *L, void **ud)

And a lot of missing commands in lua_ahkfunctions.ahk (like WinActivate, MouseMove etc)
Back to top
View user's profile Send private message
Thrawn



Joined: 12 May 2008
Posts: 30
Location: Germany

PostPosted: Thu May 14, 2009 4:04 pm    Post subject: Reply with quote

I've just finished wrapping most of the autohotkey functionality to lua - i'm still missing some 'run that lua-function, when that label gets called'-stuff, but finally it will look like this (working example):
Code:
#include lua_ahkfunctions.ahk

hDll := lua_loadDll("lua51.dll")
l := luaL_newstate()

luaL_openlibs(l)
lua_registerAhkFunction(l)

code =
(
   -- Start
   Hotkey("#3","boxy")
   Hotkey("#6","endme")

   function endme()
       Gosub("OnExit")
   end

   function boxy ()
       Msgbox("this lua-function has been called by hotkey")
   end
   -- End
)
luaL_dostring(l, code)

return


OnExit:
   lua_close(l)
   lua_UnloadDll(hDll)
   ExitApp
Back to top
View user's profile Send private message
Thrawn



Joined: 12 May 2008
Posts: 30
Location: Germany

PostPosted: Mon May 18, 2009 9:42 pm    Post subject: Reply with quote

A very (very very) basic IDE demonstration realized in ahk (uses HiEdit):



zip containing everything
Back to top
View user's profile Send private message
m2mm4m
Guest





PostPosted: Sun Nov 15, 2009 5:34 am    Post subject: AHK + LUA Interop (stdlib), proof of concept Reply with quote

Big Thank you
--
Sig _Christopher (M2M)
RefCode:444CcdTCcdds p3v4b04
void DeadEnds() {for(;Wink;} // £-)
Back to top
entropic



Joined: 21 Dec 2008
Posts: 181

PostPosted: Mon Nov 16, 2009 4:11 am    Post subject: Reply with quote

Thank you very much for your work Smile
Back to top
View user's profile Send private message
Guest_AutoHotkey_L
Guest





PostPosted: Sun May 16, 2010 5:49 am    Post subject: Thank you and a few tweaks Reply with quote

Very nice!

I encountered a few stumbling blocks in example_callLuaFromAhk.ahk via the lua.zip file in the original post.

The first was an issue with function names. Making the following changes seemed to fix things:

    lua_newstate -> luaL_newstate
    lua_openlibs -> luaL_oepnlibs
    lua_dofile -> luaL_dofile

Another issue was that just the 2 lua dlls were not enough to get things working in the local environment. I copied the Microsoft.VC80.CRT directory (which comes with lua -- try looking in lua5_1_4_Win32_bin.zip off of Lua Binaries Download) into the directory where lua.zip was unzipped.

I think that's all that was necessary here.

FWIW, below is a modified version of example_callLuaFromAhk.ahk that seems to be working here.

Code:

#NoEnv
#Include lua.ahk
;
hDll := lua_loadDll("lua51.dll")
l := luaL_newstate()
luaL_openlibs(l)
luaL_dofile(l, "example_callLuaFromAhk.lua")
sum := luaadd(10, 15)
MsgBox, % "The sum is " . sum
lua_close(l)
lua_UnloadDll(hDll)
Return

luaadd(x, y)
{
  global l
  ; the function name
  lua_getglobal(L, "add")
  ; the first argument
  lua_pushnumber(L, x)
  ; the second argument
  lua_pushnumber(L, y)
  ; call the function with 2 arguments, return 1 result
  lua_call(L, 2, 1)
  ; get the result
  sum := lua_tointeger(L, -1)
  lua_pop(L, 1)
  Return, sum
}
Back to top
Guest_AutoHotkey_L
Guest





PostPosted: Sun May 16, 2010 6:06 am    Post subject: Reply with quote

Thrawn wrote:
...but finally it will look like this (working example):

Prepending:

Code:

  #include lua.ahk

to the top of the code helped to get the working example working here Smile
Back to top
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group