Skip to content

Instantly share code, notes, and snippets.

Created May 28, 2009 01:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/119030 to your computer and use it in GitHub Desktop.
Save anonymous/119030 to your computer and use it in GitHub Desktop.
import ctypes
import ctypes.util
# load liblua5.1.so
liblua_path = ctypes.util.find_library("lua5.1")
liblua = ctypes.CDLL(liblua_path)
# create state
state = liblua.luaL_newstate()
# load standard libraries
liblua.luaL_openlibs(state)
# macros from lua.h
liblua.LUA_GLOBALSINDEX = -10002
liblua.lua_pop = lambda state, n: liblua.lua_settop(state, - n - 1)
# load script: returns 0 if success
script = 'print("Hello " .. "World")\n'
liblua.luaL_loadbuffer(state, script, len(script), "<snip>")
# call script: args: state, numargs, numresults, returns 0 if success
#liblua.lua_pcall(state, 0, 0, 0)
liblua.lua_call(state, 0, 0)
# call calc
script = 'return 2 + 3\n'
liblua.luaL_loadbuffer(state, script, len(script), "<snip>")
# pcall with nresults
liblua.lua_call(state, 0, 1)
# get result
print liblua.lua_tointeger(state, liblua.lua_gettop(state))
# pop result
liblua.lua_pop(state, liblua.lua_gettop(state))
# call with global vars (= global table's field)
script = 'return a ^ b\n'
liblua.luaL_loadbuffer(state, script, len(script), "<snip>")
# set a
liblua.lua_pushinteger(state, 2);
liblua.lua_setfield(state, liblua.LUA_GLOBALSINDEX, "a")
# set b
liblua.lua_pushinteger(state, 10);
liblua.lua_setfield(state, liblua.LUA_GLOBALSINDEX, "b")
# call
liblua.lua_call(state, 0, 1)
print liblua.lua_tointeger(state, liblua.lua_gettop(state))
liblua.lua_pop(state, liblua.lua_gettop(state))
# call function
script = '''
return function (x, y)
return x ^ y
end
'''
liblua.luaL_loadbuffer(state, script, len(script), "<snip>")
# load func on stack
liblua.lua_call(state, 0, 1)
# push args
liblua.lua_pushinteger(state, 2)
liblua.lua_pushinteger(state, 3)
# call with nargs and nresults
liblua.lua_call(state, 2, 1)
print liblua.lua_tointeger(state, liblua.lua_gettop(state))
liblua.lua_pop(state, liblua.lua_gettop(state))
# register function and call it
# define lua_CFunction and lua_pushcfunction macro
lua_CFunction = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p)
liblua.lua_pushcfunction = (
lambda state, func: liblua.lua_pushcclosure(state, func, 0))
# external cfunction defined by python
def luacfunc_sum(state):
print("SUM")
top = liblua.lua_gettop(state) # number of params
# get params: index started from 1
args = [liblua.lua_tointeger(state, i + 1) for i in range(top)]
ret = sum(args)
# push results
liblua.lua_pushinteger(state, ret)
return 1 # returns number of result
# wrap lua_CFunction and pushcfunction
func = lua_CFunction(luacfunc_sum)
liblua.lua_pushcfunction(state, func)
# push args
for i in range(10): liblua.lua_pushinteger(state, i + 1)
# call
liblua.lua_call(state, 10, 1)
# get result
print(liblua.lua_tointeger(state, liblua.lua_gettop(state)))
# finish state
liblua.lua_close(state)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment