C/Invoke

Easily call C from any language.

General Info

The C/Invoke Lua Binding uses the new Lua module system, so to use C/Invoke in your Lua programs, load the module like so:

require("cinvoke_lua")

To call C functions easily without writing a Lua module, declare a new instance of the clibrary class to load a dynamic library. The clibrary instance has methods which allow you to load functions and variables, similar to dlopen() and dlsym() on UNIX, except that you also specify the types of the parameters and the return value:

libc = clibrary.new("libc.so.6")

getpass = libc:get_function(Cstring, "getpass", Cstring)

Here we load libc.so.6 (you will have to adjust this for operating systems other than GNU/Linux) and then call get_function on the returned instance. We pass arguments to get_function to specify a function named 'getpass' which returns a type Cstring (essentially a const char *) and takes a single argument of type Cstring. get_function returns a callable Lua function object, which we assign to a variable also named getpass. This function is now usable:

pass = getpass("Enter a password: ")
print("You entered " .. pass)

Thus we have now integrated the previously unavailable getpass() function into Lua, without writing any C!

The clibrary class also has a method to create a callback, which is analogous to a C function pointer, and which allows C libraries to call Lua functions. There is also a cstructure class for defining struct types, as well as a cinv class which provides global helper methods to assist with data marshalling.

How Types Are Marshaled

There are two sorts of types in cinvoke_lua, built-in and user-defined. The list of built-in types is in the class reference below, and includes most of the basic types from C (integers, floating point values, etc.). These are marshaled to and from Lua as one would generally expect. Values of type Cchar are marshaled as Lua strings with length 1, not as their byte (integer) value.

Another built-in type is Cstring, which as mentioned earlier is useful for marshaling constant strings. Note we must emphasize the "constant"; Lua strings are immutable and passing them to a function which writes to their memory is extremely bad. You can also have functions which return string values, in which case the value returned is truncated at the first \0 character.

This limitation on returning string data as well as almost any other limitation can be overcome with the use of arrays and pointers. To declare an array type, use the cinv.array function on a non-array type. Arrays in Lua are represented in the normal manner with a table:

strcpy = libc:get_function(Cptr, "strcpy", cinv.array(Cchar), Cstring);

buf = { "a", "b", "c", "d" }

strcpy(buf, "ef")

-- buf is now { "e", "f", "\0", "d" }

As you can see, with an array you can have values written back to Lua via parameters. This function also uses the Cptr built-in type as the return type. A ptr is an opaque object (actually represented by a string) which can be used to send or receive raw pointer values to C. They can then be used with functions such as cinv.ptr_to_array and cinv.ptr_to_struct to marshal values which would otherwise be impossible for C/Invoke to determine (for example, returning an array directly from a function is not allowed because C/Invoke doesn't know the length of the returned value). Using ptrs also allows you to capture data returned by functions like malloc() and then later return their pointer values back to the C library.

In general, you can use arrays whenever you wish to pass a pointer value as a parameter (in C, an array with one element and a pointer are essentially the same). Ptrs are useful for return values as well as situations where you must hand-marshal parameters. If you wish to pass a NULL value to a function, C/Invoke allows you to pass a nil value for an array or ptr. Ptr params will also accept the integer 0 as a NULL value.

The cstructure class contains one method to create a new structure type. For example, to create the equivalent of the following C definition:

struct Foo {
	int i1;
	short s1;
};

void myfunc(struct Foo *f);

One would do the following:

Foo = cstructure.new(
	Cint, "i1",
	Cshort, "s1"
)
myfunc = mylib:get_function(Cvoid, "myfunc", cinv.array(Foo))

And to use them:

s = { i1 = 1, s1 = 2 }
myfunc({s}) -- note extra level of indirection to pass in an array

Struct types cannot be passed by value, only in arrays and marshaled by hand with pointers.

The final built-in type is Ccallback, which represents all C function pointers. To create an instance of a callback, use the clibrary:new_callback method, passing the Lua function you would like to call instead of the name of the function to load as in get_function (this method is a member of clibrary because it uses the calling convention that the library was declared with):

C:

void myfunc(void (*cb)(int)) {
	cb(1);
}

Lua:

function lua_cb(i)
	print(i)
end

myfunc = mylib:get_function(Cvoid, "myfunc", Ccallback);
cbobj = mylib:new_callback(Cvoid, lua_cb, Cint);

myfunc(cbobj) -- prints "1"

A warning: you should only use callbacks in situations where all calls to the callback are done inside the called function. This will ensure that the Lua context being called back to is still active. It is especially dangerous for a C function to keep a reference to a callback and then call it later in another thread; the Lua object holding the callback may have been garbage collected and the Lua interpreter is not thread safe.

Class Reference

Built-in Types

Cvoid

A placeholder to declare a function with no return value.

Cchar

The char type is always 1 byte wide. This type is marshaled as a Lua string with length 1.

Cshort

The short type is marshaled as an integer.

Cint

The int type is marshaled as an integer.

Clong

The long type is marshaled as an integer.

Clonglong

The long long integer type is available on some platforms; it is typically used to represent an 8-byte integer on 32-bit machines.

Cint16

This integer type is aliased to the type which is two bytes wide on the current platform.

Cint32

This integer type is aliased to the type which is four bytes wide on the current platform.

Cint64

This integer type is aliased to the type which is eight bytes wide on the current platform.

Cfloat

C floating point values are marshaled as a Lua number.

Cdouble

C double-precision floating point values are marshaled as a Lua member.

Cstring

The string type allows Lua strings to be passed to functions accepting a const char *. Do not use this type for mutable arrays or to return a value from a function which is not \0 terminated.

Cptr

This type represents a Pointer value, however large that may be on the current platform. Values of this type should only be either returned from a C function, or the value nil or the integer 0. You can pass values of this type to many members of the cinv class to marshal values which would otherwise be difficult to for C/Invoke to process.

Ccallback

Represents any C function pointer, regardless of the prototype. Valid values are generated (with prototype information) by the clibrary:new_callback method.

Classes

cinv

array(type)

Returns a new type representing a C array (passed by reference) of the specified type. The passed type is not modified.

chararray_to_string(arr[, len])

Converts a Lua array (a table with integer keys) of values of type Cchar to a Lua string. If len is not specified, the length is determined by the length of the array.

string_to_chararray(str[, includenil])

Converts a Lua string to a Lua array (a table with integer keys) of values of type Cchar. If includenil is true, then the last element of the array will be a \0 byte value.

ptr_to_string(ptr[, len])

Converts a ptr value (presumably pointing to an array of chars) to a Lua string. If len is not specified, conversion continues up until the first \0 character.

ptr_to_array(ptr, type, len)

Converts a ptr value to a Lua array of values of the specified type. This method provides a way to unmarshal return values consisting of pointers to structures.

ptr_to_struct(ptr, type)

Converts a ptr value to a Lua table, with the keys and values set to the fields of the specified structure type. Essentially equivalent to cinv.ptr_to_array(ptr, type, 1)[1].

ptr_to_callback(ptr)

Converts a ptr value to a value suitable for passing as a Ccallback. Useful for C functions which return function pointers.

callback_to_ptr(cb)

Converts a C/Invoke callback returned by clibrary:new_callback to a raw ptr value. The returned ptr points to managed memory inside the Lua interpreter, and the same cautions apply when using it as when passing callback values to a function.

sizeof(type)

Returns the number of bytes needed to hold the given type.

clibrary

new(libname[, callingconv])

Opens a C shared library. Libname is a platform-specific string containing the name of the library to load, i.e. "libc.so" or "kernel32.dll". callingconv specifies a calling convention to use. Currently supported are "cdecl", "stdcall", "fastcall", and "default". If callingconv is not specified then the default is used. Platforms other than Microsoft Windows typically only use the default calling convention. On Windows, stdcall should be used for all Win32 API functions.

dispose(self)

Unloads the given library instance from memory.

get_function(self, rettype, name, ...)

Creates a new C function object in the given library, and returns a callable Lua function value. If the function returns void, specify Cvoid for rettype, otherwise specify the correct return type. The name parameter is the name of the symbol in the shared libary to load. If the function takes parameters, pass the types of the parameters in order after the name. Functions with variable argument lists are not supported. For other limitations, see the documentation on specific types.

new_callback(self, rettype, cbfunc, ...)

Creates a callback object which can be passed as a function pointer to a C function. The arguments are the same as for get_function, except that instead of a symbol name, a Lua function is passed. This function will then get called when the C code calls through the function pointer. Because C/Invoke cannot control the values being passed into and returned from the callbacks, there are additional constraints on the types of arguments a callback can take; in particular, arrays are not allowed as arguments.

It is highly reccomended to only use callbacks in circumstances where the passed function pointer is called within the context of the C function, and nowhere else. Storing a pointer to a Lua callback and calling it later in the program execution could lead to undefined behavior.

tie_init(self, type, name)

Creates an entry in the library instance for a tied variable, i.e. a symbol in a shared library which points to a global C variable. Only basic types (not strings, structs, callbacks, etc.) can be tied.

tie_get(self, name)

Returns the value of a tied C variable as a Lua object.

tie_set(self, name, value)

Sets the value of a tied C variable.

cstructure

new(type, name[, type, name ...])

Creates a new structure type. Each pair of arguments to this function adds a member to the structure. Once a function with the returned type is declared, a table value with the given name values as keys can be used to represent an instance of this structure. Structures cannot be passed to C functions by value; they must be passed in an array. Structures cannot contain arrays or callbacks, but they can contain embedded in-line structure types. For example, the following C definition:

struct Inner {
	int u;
	int v;
};

struct Outer {
	struct Inner in;
	float out;
};

Can be represented in Lua as shown:

Inner = cstructure.new(
	Cint, "u",
	Cint, "v"
)
Outer = cstructure.new(
	Inner, "in",
	Cfloat, "out"
)