Is there a foreign function Interface (FFI)?

Alien is a Lua binding to libffi.

Here is an example of binding to the C runtime; note that Windows is a special case requiring an explicit load. Alien handles the tedious part of binding to C for us:

require "alien"
if alien.platform == "windows" then
 libc = alien.load("msvcrt.dll")
else
 libc = alien.default end libc.malloc:types("pointer", "int")
libc.free:types("void", "pointer")
libc.strcpy:types("void", "pointer", "string")
libc.strcat:types("void", "pointer", "string")
libc.puts:types("void", "string")
local foo = libc.malloc(string.len("foo") + string.len("bar") + 1)
libc.strcpy(foo, "foo")
libc.strcat(foo, "bar")
libc.puts(foo)
libc.strcpy(foo, "bar")
libc.puts(foo)
libc.puts("Yeah!")
libc.free(foo)

Here is the classic GTK+ "Hello, World":

local gtk,p,i=alien.load("/usr/lib/libgtk-x11-2.0.so.0"),"pointer","int"
gtk.gtk_init:types(nil,p,p)
gtk.gtk_message_dialog_new:types(p,p,i,i,i,p)
gtk.gtk_dialog_run:types(i,p)
gtk.gtk_init(nil,nil)
gtk.gtk_dialog_run(gtk.gtk_message_dialog_new(nil,0,0,1,"Alien Rocks!"))

People can get a little bit overexcited at this point and to try doing non-trivial GTK+ applications with Alien, but there are a lot of functions and constants involved; you are better off with a full-featured GTK binding like lua-gtk. But if you just want your script to put up a message, it works fine.

One issue that may bite you with Alien is that you need the full path to the shared library on Unix (Windows has a more relaxed shared library path) and these paths will move around depending on the whim of the distribution maintainers. For example, the shared libraries are in /usr/lib64 on RedHat/SuSE x86_64 distributions (but not in Debian/Ubuntu).

How fast is Alien? Calling sin through Alien takes about 3 times longer than math.sin. So there is a definite cost for accessing functions in this way, but in many cases the actual work done by the function is much larger than the call overhead.

4.5.1 LuaJIT FFI

LuaJIT's built-in FFI provides a very fast way for Lua programs to access C functions and structures. Provided LuaJIT supports your platform, it will be as fast (if not faster) than writing C extensions. Simple C function and structure declarations are directly understood:

ffi.cdef[[
void Sleep(int ms);
]]

after which the function can be called directly as ffi.C.sleep.

C arrays and structures can be directly created and accessed - note that arrays are zero-based:

> ffi = require 'ffi'
> arr = ffi.new("double[?]",20)
> for i = 1,20 do arr[i-1] = i end
> = arr[10];
11
 > ffi.cdef [[struct _point {double x,y;};]]
 > point = ffi.new("struct _point")
> point.x, point.y = 10,20
> = point.x, point.y
10 20

5 Hardware



Back