541 lines
23 KiB
HTML
541 lines
23 KiB
HTML
<h1>Alien – Pure Lua extensions</h1>
|
|
|
|
<h2>Status</h2>
|
|
|
|
<p>This is Alien version 0.5.0.</p>
|
|
|
|
<h2>Changelog</h2>
|
|
|
|
<ul>
|
|
<li>0.5.0
|
|
|
|
<ul>
|
|
<li>new functions alien.memcpy and alien.memset</li>
|
|
<li>new type “p” for alien.struct.pack and unpack, to pack pointers</li>
|
|
<li>new alien.struct.offset function to get the offset of a given record</li>
|
|
<li>buf:tostring now has optional “offset” argument</li>
|
|
<li>buf:topointer now has optional “offset” argument</li>
|
|
<li>added unsigned numbers: uint, ulong, ushort, and “ref uint”</li>
|
|
<li>basic support for declarative strucutures</li>
|
|
<li>unified treatment of funcitons and callbacks in the source</li>
|
|
<li>fixed segfault when collecting 0-arg functions</li>
|
|
</ul>
|
|
</li>
|
|
<li>0.4.1
|
|
|
|
<ul>
|
|
<li>fixes bug where Alien was always using cdecl abi for Windows (except in callbacks)</li>
|
|
<li>fixes build on PPC OSX.</li>
|
|
</ul>
|
|
</li>
|
|
<li>0.4.0
|
|
|
|
<ul>
|
|
<li>Windows support – stdcall ABI, including stdcall callbacks</li>
|
|
<li>alternative syntax for defining types</li>
|
|
<li>mutable buffers, wrapping lightuserdata in a buffer</li>
|
|
<li>alien.to<em>type</em> functions take optional length argument</li>
|
|
<li>callbacks are callable from Lua</li>
|
|
<li>alien.funcptr turns a function pointer into an alien function</li>
|
|
<li>improved library finding on Linux/FreeBSD, using ldconfig</li>
|
|
<li>alien.table utility function (wrapper for lua_createtable, useful for extensions)</li>
|
|
<li>alien.align utility function to get data structure alignment</li>
|
|
<li>arrays built on mutable buffers, with bounds checking</li>
|
|
<li>fixed a build bug on Linux ARM</li>
|
|
</ul>
|
|
</li>
|
|
<li>0.3.2 – fixes callback bug on NX-bit platforms</li>
|
|
<li>0.3.1 – initial release with libffi</li>
|
|
<li>0.3 – retracted due to license conflict</li>
|
|
</ul>
|
|
|
|
|
|
<h2>What is Alien</h2>
|
|
|
|
<p><em>Alien</em> is a Foreign Function Interface (FFI) for Lua. An FFI lets you
|
|
call functions in dynamic libraries (.so, .dylib, .dll, etc.) from Lua
|
|
code without having to write, compile and link a C binding from the
|
|
library to Lua. In other words, it lets you write extensions that call
|
|
out to native code using just Lua.</p>
|
|
|
|
<p>Be careful when you use Alien, I tried to make it as safe as possible,
|
|
but it is still very easy to crash Lua if you make a mistake. Alien
|
|
itself is not as robust as a standard Lua extension, but you can use
|
|
it to write extensions that won’t crash if you code them well.</p>
|
|
|
|
<p>Alien works on Unix-based systems and Windows. It has been tested on Linux x86,
|
|
Linux x64, Linux ARM, FreeBSD x86, Windows x86, OSX x86, and OSX PPC. The Windows
|
|
binary uses MSVCR80.DLL for compatibility with LuaBinaries.</p>
|
|
|
|
<h2>Installing Alien</h2>
|
|
|
|
<p>The best way to install Alien is through
|
|
<a href="http://luarocks.org">LuaRocks</a>. Just do <code>luarocks install alien</code>. You may need
|
|
root permissions to do this, depending on your LuaRocks configuration.</p>
|
|
|
|
<p>Go to the Alien rock directory to see local copies of this
|
|
documentation, as well as the test suite. If you are in the path of
|
|
the test suite (<code>tests</code>) you can run the suite with:</p>
|
|
|
|
<pre><code>lua -l luarocks.require test_alien.lua
|
|
</code></pre>
|
|
|
|
<p>If everything is ok you should see no output.</p>
|
|
|
|
<p>Alien installs to modules, <code>alien</code> and <code>alien.struct</code>. The latter is a
|
|
slightly modified version of Roberto Ierusalimschy’s <a href="http://www.inf.puc-rio.br/~roberto/struct">struct
|
|
library</a> that can unpack
|
|
binary blobs (userdata) instead of just strings.</p>
|
|
|
|
<h2>Basic Usage</h2>
|
|
|
|
<p>Loading a dynamic library is very simple; Alien by default assumes a
|
|
naming scheme of lib<em>name</em>.dylib for OSX and lib<em>name</em>.so for other
|
|
Unix systems. If <em>name</em> is not one of the
|
|
functions the <code>alien</code> module exports then you can get a reference to
|
|
the library with <code>alien.</code><em><code>name</code></em>. Otherwise (for example, to load a
|
|
library called <em>libwrap.so</em>) you have to use <code>alien.load("wrap")</code>.</p>
|
|
|
|
<p>You can also specify the full name of the library by calling
|
|
<code>alien.load</code> with a path or with the appropriate extension, such as
|
|
<code>alien.load("mylibs/libfoo.so")</code> or <code>alien.load("libfoo.so")</code>.
|
|
Either way you get back a reference
|
|
to the library that you will use to access its functions.</p>
|
|
|
|
<p>You can also get a reference to the currently running module using
|
|
<code>alien.default</code>, this lets you get references to any function exported
|
|
by the module and its transitive dependencies on ELF and Mach-O systems.</p>
|
|
|
|
<p>Once you have a reference to a library you can get a reference to an
|
|
exported function with <em>libref.funcname</em>. For example:</p>
|
|
|
|
<pre><code>> def=alien.default
|
|
> =def.puts
|
|
alien function puts, library defaults
|
|
>
|
|
</code></pre>
|
|
|
|
<p>To use a function you first have to tell Alien the function prototype,
|
|
using <em>func:types(ret_type, arg_types…)</em>, where the types are one of
|
|
the following strings: “void”, “int”, “uint”, “double”, “char”, “string”,
|
|
“pointer”, “ref int”, “ref uint”, “ref double”, “ref char”, “callback”, “short”, “ushort”,
|
|
“byte”, “long”, “ulong”, and “float”. Most correspond directly to C types;
|
|
<em>byte</em> is a signed char, <em>string</em> is <em>const char*</em>, <em>pointer</em> is <em>void*</em>,
|
|
<em>callback</em> is a generic function pointer, and <em>ref char</em>, <em>ref int</em>
|
|
and <em>ref double</em> are by reference versions of the C types. Continuing
|
|
the previous example:</p>
|
|
|
|
<pre><code>> def.puts:types("int", "string")
|
|
> def.puts("foo")
|
|
foo
|
|
>
|
|
</code></pre>
|
|
|
|
<p>As you can see, after defining the prototype you can call the function
|
|
just as a Lua function. Alien converts Lua numbers to the C numeric
|
|
types, converts <em>nil</em> to <em>NULL</em> and Lua strings to <em>const char*</em> for
|
|
<em>string</em>, and converts <em>nil</em> to <em>NULL</em> and userdata to <em>void*</em> for
|
|
<em>pointer</em>. The conversions work in reverse for the return value (with
|
|
the <em>pointer</em> type converted to a light userdata).</p>
|
|
|
|
<p>By reference types are special; Alien allocates space on the stack for
|
|
the argument, copies the Lua number you passed to it (converting
|
|
appropriately), then calling the function with the address of this
|
|
space. Then the value is converted back to a Lua number and returned
|
|
after the function normal return value. An example, using <em>scanf</em>:</p>
|
|
|
|
<pre><code>> scanf = alien.default.scanf
|
|
> scanf:types("int", "string", "ref int", "ref double")
|
|
> _, x, y = scanf("%i %lf", 0, 0)
|
|
23 42.5
|
|
> =x
|
|
23
|
|
> =y
|
|
42.5
|
|
</code></pre>
|
|
|
|
<p>You have to pass a value even if the function does not use it, as you
|
|
can see above.</p>
|
|
|
|
<p>Another way to specify types is by passing a table to <em>func:types</em>. The array
|
|
part of this table shoudl have one item for each parameter, and you can also pass
|
|
two hash keys, <em>ret</em>, the function’s return type (defaults to <code>int</code> as usual), and
|
|
<em>abi</em>, the function’s calling convention (useful for Windows, where you can specify “stdcall” as the
|
|
ABI for <code>__stdcall</code> functions. The default ABI is always “default”, and all systems
|
|
also support “cdecl”, the usual C calling convention. On systems that don’t have the
|
|
stdcall convention “stdcall” is the same as “default”.</p>
|
|
|
|
<p>This is the previous example using this alternate definition:</p>
|
|
|
|
<pre><code>> scanf = alien.default.scanf
|
|
> scanf:types{ ret = "int", "string", "ref int", "ref double" }
|
|
> _, x, y = scanf("%i %lf", 0, 0)
|
|
23 42.5
|
|
> =x
|
|
23
|
|
> =y
|
|
42.5
|
|
</code></pre>
|
|
|
|
<p>If you get raw function pointer (returned from a function, for example, or
|
|
passed to a callback), you can turn it into an Alien function with <code>alien.funcptr(fptr)</code>.
|
|
This returns an Alien function object that you can type and call function normally.</p>
|
|
|
|
<h2>Buffers</h2>
|
|
|
|
<p>The basic usage is enough to do a lot of interfacing with C code,
|
|
specially with well-behaved libraries that handle their own memory
|
|
allocation (the Lua C API is a good example of such an API). But there
|
|
are libraries that do not export such a well-behaved API, and require
|
|
you to allocate memory that is mutated by the library. This prevents
|
|
you from passing Lua strings to them, as Lua strings have to be
|
|
immutable, so Alien provides a <em>buffer</em> abstraction. The function
|
|
<code>alien.buffer</code> allocates a new buffer. If you call it with no
|
|
arguments it will allocate a buffer with the standard buffer size for
|
|
your platform. If call it with a number it will allocate a buffer with
|
|
this number of bytes. If you pass it a string it will allocate a
|
|
buffer that is a copy of the string. If you pass a light userdata
|
|
it will use this userdata as the buffer (be careful with that).</p>
|
|
|
|
<p>After making a buffer you can pass it in place of any argument of
|
|
<em>string</em> or <em>pointer</em> type. To get back the contents of the buffer you
|
|
use <code>buf:tostring</code>, and again you can either pass the number of
|
|
characters to read from the buffer or don’t pass anything, which treat
|
|
the buffer as a C string (read until finding a <em>\0</em>). You can also
|
|
call <code>buf:len</code>, which calls <em>strlen</em> on the buffer. Finally,
|
|
<code>tostring(buf)</code> is the same as <code>buf:tostring()</code>.</p>
|
|
|
|
<p>An example of how to use a buffer:</p>
|
|
|
|
<pre><code>> gets = alien.default.gets
|
|
> gets:types("pointer", "string")
|
|
> buf = alien.buffer()
|
|
> gets(buf)
|
|
Foo bar
|
|
> =tostring(buf)
|
|
Foo bar
|
|
>
|
|
</code></pre>
|
|
|
|
<p>You can access the i-th character of a buffer with <code>buf[i]</code>, and you can
|
|
set its value with <code>buf[i] = v</code>. Notice that these are C characters (bytes),
|
|
not Lua 1-character strings, so you need to use <code>string.char</code> and <code>string.byte</code>
|
|
to convert between Lua characters and C characters. <strong>Access to Alien buffers
|
|
from Lua is 1-based instead of 0-based</strong>.</p>
|
|
|
|
<p>You can also get and set other values by using <em>buf:get(offset, type)</em>, and
|
|
set it by <em>buf:set(offset, val, type)</em>. The offset is in bytes, <em>not</em> in elements, so
|
|
if <em>buf</em> has three “int” values their offsets are 1, 5 and 9, respectively, assuming
|
|
each “int” is four bytes long.</p>
|
|
|
|
<p>All get and set operations do no bounds-checking, so be extra careful, or use the
|
|
safer alien.array abstraction that is built on top of buffers.</p>
|
|
|
|
<h2>Arrays</h2>
|
|
|
|
<p>Arrays are buffers with an extra layer of safety and sugar on top. You create an array
|
|
with <code>alien.array(type, length)</code>, where <em>type</em> is the Alien type of the array’s elements,
|
|
and length is how many elements the array has. After creating an array <em>arr</em> you can get the
|
|
type of its elements with <em>arr.type</em>, how many elements it has with <em>arr.length</em>, and the
|
|
size (in bytes) of each element with <em>arr.size</em>. The underlying buffer is <em>arr.buffer</em>.</p>
|
|
|
|
<p>You can access the i-th element with <em>arr[i]</em>, and set it with <em>arr[i] = val</em>. Type
|
|
conversions are the same as with buffers, or function calls. Storing a string or userdata
|
|
in an array pins it so it won’t be collected while it is in the array.</p>
|
|
|
|
<p>For convenience <code>alien.array</code> also accepts two other forms: <code>alien.array(type, tab)</code> creates
|
|
an array with the same length as <em>tab</em> and initializes it with its values;
|
|
<code>alien.array(type, length, buf)</code> creates an array with <em>buf</em> as the underlying buffer. You can
|
|
also iterate over the array’s contents with <code>arr:ipairs()</code>.</p>
|
|
|
|
<p>The following example shows an use of arrays:</p>
|
|
|
|
<pre><code>local function sort(a, b)
|
|
return a - b
|
|
end
|
|
local compare = alien.callback(sort, "int", "ref int", "ref int")
|
|
|
|
local qsort = alien.default.qsort
|
|
qsort:types("void", "pointer", "int", "int", "callback")
|
|
|
|
local nums = alien.array(t, { 4, 5, 3, 2, 6, 1 })
|
|
qsort(nums.buffer, nums.length, nums.size, compare)
|
|
for i, v in nums:ipairs() do print(v) end
|
|
</code></pre>
|
|
|
|
<p>This prints numbers one to six on the console.</p>
|
|
|
|
<h2>Structs</h2>
|
|
|
|
<p>Alien also has basic support for declarative structs that is also implemented as a layer of sugar
|
|
on the basic buffers. The <code>alien.defstruct(description)</code> function creates a struct type with the
|
|
given description, which is a list of pairs with the name and type of each field, where the type is any
|
|
basic alien type (no structs inside structs yet). For example:</p>
|
|
|
|
<pre><code>rect = alien.defstruct{
|
|
{ "left", "long" },
|
|
{ "top", "long" },
|
|
{ "right", "long" },
|
|
{ "bottom", "long" }
|
|
}
|
|
</code></pre>
|
|
|
|
<p>This creates a new struct type with four fields of type “long”, and stores it in <code>rect</code>. To create an
|
|
instance of this structure (backed by a buffer) call <code>rect:new()</code>. You can then set the fields of the
|
|
struct just like you do on a Lua table, like <code>r.left = 3</code>. To get the underlying buffer (to pass it
|
|
to a C function, for example) you have to call the instance, <code>r()</code>. Continuing the example:</p>
|
|
|
|
<pre><code>r = rect:new()
|
|
r.left = 2
|
|
doubleleft = alien.rectdll.double_left
|
|
doubleleft:types("void", "pointer")
|
|
doubleleft(r()))
|
|
assert(r.left == 4)
|
|
</code></pre>
|
|
|
|
<p>You can also pass a buffer or other userdata to the <code>new</code> method of your struct type, and in this case this will
|
|
be the backing store of the struct instance you are creating. This is useful for unpacking a foreign struct that
|
|
a C function returned.</p>
|
|
|
|
<h2>Pointer Unpacking</h2>
|
|
|
|
<p>Alien also provides three convenience functions that let you
|
|
dereference a pointer and convert the value to a Lua type:</p>
|
|
|
|
<ul>
|
|
<li><code>alien.tostring</code> takes a userdata (usually returned from a function
|
|
that has a <em>pointer</em> return value), casts it to <em>char*</em>, and
|
|
returns a Lua string. You can supply an optional size argument (if
|
|
you don’t Alien calls <em>strlen</em> on the buffer first).</li>
|
|
<li><code>alien.toint</code> takes a userdata, casts it to <em>int*</em>,
|
|
dereferences it and returns it as a number. If you pass it a number
|
|
it assumes the userdata is an array with this number of elements.</li>
|
|
<li><code>alien.toshort</code>, <code>alien.tolong</code>, <code>alien.tofloat</code>, and
|
|
<code>alien.todouble</code> are like <code>alien.toint</code>, but works with
|
|
with the respective typecasts. Unsigned versions are also available.</li>
|
|
</ul>
|
|
|
|
|
|
<p>The numeric alien.to<em>type</em> functions take an optional second argument that
|
|
tells how many items to unpack from the userdata. For example, if ptr is
|
|
a pointer to an array of four floats, the following code unpacks this array:</p>
|
|
|
|
<pre><code>> fs = alien.tofloat(ptr, 4)
|
|
> =#fs
|
|
4
|
|
>
|
|
</code></pre>
|
|
|
|
<p>Use these functions with extra care, they don’t make any safety
|
|
checks. For more advanced unmarshaling use the <code>alien.struct.unpack</code>
|
|
function.</p>
|
|
|
|
<h2>Tags</h2>
|
|
|
|
<p>A common pattern when wrapping objects from C libraries is to put a
|
|
pointer to this object inside a full userdata, then associate this userdata
|
|
with a metatable that is associated with a string tag. This tag is
|
|
used to check if the userdata is a valid userdata in each function
|
|
that uses it. As the userdata is a full userdata it also can have a
|
|
<code>__gc</code> metamethod for resource reclamation.</p>
|
|
|
|
<p>Alien has three functions that let you replicate this pattern on your
|
|
extensions:</p>
|
|
|
|
<ul>
|
|
<li><code>alien.tag(*tagname*)</code> creates a new metatable with tag <em>tagname</em> if one
|
|
does not exist, or returns the metatable with this tag. The
|
|
namespace for tags is global, so a good pattern is to prefix the tag
|
|
name with the name of your module (such as <em>mymod_mytag</em>).</li>
|
|
<li><code>alien.wrap(*tagname*, ...)</code> creates a full userdata, tags it with
|
|
the metatable associated with <em>tagname</em>, stores the values
|
|
you passed, then returns the full userdata. Valid values are <em>nil</em>,
|
|
integers and other userdata.</li>
|
|
<li><code>alien.unwrap(*tagname*, obj)</code> tests if <em>obj</em> is tagged with
|
|
<em>tagname</em>, throwing an error if it is not, then returns the values
|
|
previously stored in it.</li>
|
|
<li><code>alien.rewrap(*tagname*, obj, ...)</code> replaces the elements on <em>obj</em> with
|
|
new values. If you pass more values than <em>obj</em> had previously the extra
|
|
values are silently ignored. If you pass less tehn <em>obj</em> is filled with
|
|
<em>nil</em>.</li>
|
|
</ul>
|
|
|
|
|
|
<p>For example, suppose <em>libfoo</em> has a <code>create_foo</code> function that returns
|
|
a <code>Foo*</code> object. These objects have to be properly disposed by calling
|
|
<code>destroy_foo</code> when they are not used anymore. This is easy to
|
|
implement:</p>
|
|
|
|
<pre><code>local tag_foo = alien.tag("libfoo_foo")
|
|
alien.foo.create_foo:types("pointer")
|
|
alien.foo.destroy_foo_types("void", "pointer")
|
|
|
|
function new_foo()
|
|
local foo = alien.foo.create_foo()
|
|
return alien.wrap("libfoo_foo", foo)
|
|
end
|
|
|
|
tag_foo = {
|
|
__gc = function (obj)
|
|
local foo = alien.unwrap("libfoo_foo", obj)
|
|
alien.foo.destroy_foo(foo)
|
|
end
|
|
}
|
|
</code></pre>
|
|
|
|
<p>Then on any function that operates on <code>Foo*</code> types you first unwrap to
|
|
get the pointer, then pass it to the function in <em>libfoo</em>.</p>
|
|
|
|
<h2>Error Codes</h2>
|
|
|
|
<p>Several operating system functions return errors on a special variable
|
|
called <em>errno</em>. To get the value of <em>errno</em> with Alien call
|
|
<code>alien.errno()</code>.</p>
|
|
|
|
<h2>Callbacks</h2>
|
|
|
|
<p>Some libraries have functions that take <em>callbacks</em>, functions that
|
|
get called by the library. Most GUI libraries use callbacks, but even
|
|
the C library has <em>qsort</em>. Alien lets you create a callback from a Lua
|
|
function with <code>alien.callback</code>. You pass the function and the callback
|
|
prototype that the library expects. Alien will return a callback
|
|
object that you can pass in any argument of <em>callback</em> type. A simple
|
|
example, using <em>qsort</em>:</p>
|
|
|
|
<pre><code>local function cmp(a, b)
|
|
return a - b
|
|
end
|
|
local cmp_cb = alien.callback(sort, "int", "ref char", "ref char")
|
|
|
|
local qsort = alien.default.qsort
|
|
qsort:types("void", "pointer", "int", "int", "callback")
|
|
|
|
local chars = alien.buffer("spam, spam, and spam")
|
|
qsort(chars, chars:len(), alien.sizeof("char"), cmp_cb)
|
|
assert(chars:tostring() == " ,,aaaadmmmnpppsss")
|
|
</code></pre>
|
|
|
|
<p>The <em>qsort</em> function sorts an array in-place, so we have to use a
|
|
buffer.</p>
|
|
|
|
<p>Callbacks are callable from Lua just like any other Alien function, and you can freely
|
|
change their types with their “types” method.</p>
|
|
|
|
<h2>Magic Numbers</h2>
|
|
|
|
<p>C libraries are full of symbolic constants that are in truth magic
|
|
numbers, as they are replaced by the preprocessor before even the C
|
|
compiler has a chance to see them. This means that all these constants
|
|
are on header files. This also includes things such as the layout and
|
|
size of strucutres the library depends on. All this information can
|
|
change from version to version of the library, or from platform to
|
|
platform.</p>
|
|
|
|
<p>Alien provides a utility script called <em>constants</em> that makes it
|
|
easier to work with these numbers. This utility takes three arguments
|
|
on the command line: a <em>definitions file</em>, the name of the C file you
|
|
want it to generate, and the name of a Lua file that the C file will
|
|
generate when compiled and run. The definitions file can contain
|
|
preprocessor directives, blank lines, and lines with definitions
|
|
either of the form <em>identifier</em> or <em>lua_identifier</em> = <em>c_identifier</em>. The first
|
|
form is equivalent to <em>identifier</em> = <em>identifier</em>. It is best to
|
|
explain by example (from a libevent binding):</p>
|
|
|
|
<pre><code>#include <sys/types.h>
|
|
#include <event.h>
|
|
|
|
EV_SIZE = sizeof(struct event)
|
|
EV_READ
|
|
EV_WRITE
|
|
EV_TIMEOUT
|
|
EVLOOP_NONBLOCK
|
|
EVLOOP_ONCE
|
|
</code></pre>
|
|
|
|
<p>Lines with preprocessor directives are copied verbatim to the C file
|
|
<em>constants generates</em>. The above definitions file generates this C
|
|
file:</p>
|
|
|
|
<pre><code>/* Generated by Alien constants */
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <event.h>
|
|
#define LUA_FILE "event_constants.lua"
|
|
int main() {
|
|
FILE *f = fopen(LUA_FILE, "w+");
|
|
fprintf(f, "-- Generated by Alien constants\n\n");
|
|
fprintf(f, "%s = %i\n", "EV_SIZE ", sizeof(struct event));
|
|
fprintf(f, "%s = %i\n", "EV_READ", EV_READ);
|
|
fprintf(f, "%s = %i\n", "EV_WRITE", EV_WRITE);
|
|
fprintf(f, "%s = %i\n", "EV_TIMEOUT", EV_TIMEOUT);
|
|
fprintf(f, "%s = %i\n", "EVLOOP_NONBLOCK", EVLOOP_NONBLOCK);
|
|
fprintf(f, "%s = %i\n", "EVLOOP_ONCE", EVLOOP_ONCE);
|
|
fclose(f);
|
|
}
|
|
</code></pre>
|
|
|
|
<p>Which, when compile and run, generates this file on a Linux/Intel
|
|
system:</p>
|
|
|
|
<pre><code>-- Generated by Alien constants
|
|
|
|
EV_SIZE = 84
|
|
EV_READ = 2
|
|
EV_WRITE = 4
|
|
EV_TIMEOUT = 1
|
|
EVLOOP_NONBLOCK = 2
|
|
EVLOOP_ONCE = 1
|
|
</code></pre>
|
|
|
|
<p>These steps (generating the C file, compiling, generating the Lua
|
|
file) are best done in the build step of your extension.</p>
|
|
|
|
<h2>Miscellanea</h2>
|
|
|
|
<p>You can query what platform your extension is running on with
|
|
<code>alien.platform</code>. Right now this can be either “unix” or “osx”. Other
|
|
platforms will be added as they are tested. You can use this
|
|
information for conditional execution in your extensions.</p>
|
|
|
|
<p>You can get the sizes of the types Alien supports using
|
|
<code>alien.sizeof(*typename*)</code>, as the <em>qsort</em> example in the Callbacks
|
|
section shows. You can also get strucutre aligment information
|
|
with <code>alien.align(*typename*)</code>.</p>
|
|
|
|
<p>Several extensions may need to create Lua tables with preallocated
|
|
array and/or hash parts, for performance reasons (implementing a circular queue, for
|
|
example). Alien exposes the <code>lua_createtable</code> function as <code>alien.table(narray, nhash)</code>.</p>
|
|
|
|
<h2>Credits</h2>
|
|
|
|
<p>Alien is designed and implemented by Fabio Mascarenhas. It uses the
|
|
great <a href="http://sources.redhat.com/libffi">libffi</a>
|
|
library by Anthony Green (and others) to do the heavy lifting of calling to and from C. The
|
|
name is stolen from Common Lisp FFIs.</p>
|
|
|
|
<h2>License</h2>
|
|
|
|
<p>Alien’s uses the MIT license, reproduced below:</p>
|
|
|
|
<p>Copyright © 2008-2009 Fabio Mascarenhas</p>
|
|
|
|
<p>Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the “Software”), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:</p>
|
|
|
|
<p>The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.</p>
|
|
|
|
<p>THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.</p>
|