C/Invoke
Easily call C from any language.
The C/Invoke Lua Binding uses the new Lua module system, so to use C/Invokein your Lua programs, load the module like so:
require("cinvoke_lua")
To call C functions easily without writing a Lua module, declare a newinstance of the clibrary class to load a dynamic library. The clibraryinstance has methods which allow you to load functions and variables, similarto dlopen() and dlsym() on UNIX, except that you also specify the types ofthe 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 systemsother than GNU/Linux) and then call get_function on the returned instance.We pass arguments to get_function to specify a function named 'getpass' whichreturns a type Cstring (essentially a const char *) and takes a single argumentof type Cstring. get_function returns a callable Lua function object, which weassign 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() functioninto Lua, without writing any C!
The clibrary class also has a method to create a callback, which isanalogous to a C function pointer, and which allows C libraries to callLua functions. There is also a cstructure class for defining struct types,as well as a cinv class which provides global helper methods toassist with data marshalling.
There are two sorts of types in cinvoke_lua, built-in and user-defined. Thelist of built-in types is in the class reference below, and includes most ofthe basic types from C (integers, floating point values, etc.). These aremarshaled to and from Lua as one would generally expect. Values of type Ccharare marshaled as Lua strings with length 1, not as their byte (integer) value.
Another built-in type is Cstring, which as mentioned earlier is usefulfor marshaling constant strings. Note we must emphasize the "constant"; Lua strings are immutable and passing them to a function which writes to theirmemory is extremely bad. You can also have functions which return stringvalues, in which case the value returned is truncated at the first \0 character.
This limitation on returning string data as well as almost any otherlimitation can be overcome with the use of arrays and pointers. To declarean array type, use the cinv.array function on a non-array type. Arrays inLua 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 viaparameters. This function also uses the Cptr built-in type as the returntype. A ptr is an opaque object (actually represented by a string) whichcan be used to send or receive raw pointer values to C. They can then beused with functions such as cinv.ptr_to_array and cinv.ptr_to_struct tomarshal values which would otherwise be impossible for C/Invoke to determine(for example, returning an array directly from a function is not allowedbecause C/Invoke doesn't know the length of the returned value). Using ptrsalso allows you to capture data returned by functions like malloc() and thenlater return their pointer values back to the C library.
In general, you can use arrays whenever you wish to pass a pointer value asa parameter (in C, an array with one element and a pointer are essentially thesame). Ptrs are useful for return values as well as situations where youmust hand-marshal parameters. If you wish to pass a NULL value to afunction, C/Invoke allows you to pass a nil value for an array or ptr. Ptrparams 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 byhand with pointers.
The final built-in type is Ccallback, which represents all C functionpointers. To create an instance of a callback, use the clibrary:new_callbackmethod, passing the Lua function you would like to call instead of the nameof the function to load as in get_function (this method is a member of clibrarybecause 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)endmyfunc = 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 Luacontext being called back to is still active. It is especially dangerous fora C function to keep a reference to a callback and then call it later inanother thread; the Lua object holding the callback may have beengarbage collected and the Lua interpreter is not thread safe.
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 stringwith 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 istypically 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 aconst char *. Do not use this type for mutable arrays or to return a valuefrom a function which is not \0 terminated.
Cptr
This type represents a Pointer value, however large that may be on the currentplatform. Values of this type should only be either returned from a Cfunction, or the value nil or the integer 0. You can pass values of this typeto many members of the cinv class to marshal values which would otherwisebe difficult to for C/Invoke to process.
Ccallback
Represents any C function pointer, regardless of the prototype. Valid valuesare generated (with prototype information) by the clibrary:new_callback method.
cinv
array(type)
Returns a new type representing a C array (passed by reference) of thespecified 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 isnot 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 bea \0 byte value.
ptr_to_string(ptr[, len])
Converts a ptr value (presumably pointing to an array of chars) to a Luastring. If len is not specified, conversion continues up until the first \0character.
ptr_to_array(ptr, type, len)
Converts a ptr value to a Lua array of values of the specified type. Thismethod provides a way to unmarshal return values consisting of pointers tostructures.
ptr_to_struct(ptr, type)
Converts a ptr value to a Lua table, with the keys and values set to thefields of the specified structure type. Essentially equivalent tocinv.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 ptrvalue. 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 containingthe name of the library to load, i.e. "libc.so" or "kernel32.dll". callingconvspecifies a calling convention to use. Currently supported are "cdecl","stdcall", "fastcall", and "default". If callingconv is not specified then thedefault is used. Platforms other than Microsoft Windows typically only usethe default calling convention. On Windows, stdcall should be used for allWin32 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 thecorrect return type. The name parameter is the name ofthe symbol in the shared libary to load. If the function takes parameters, passthe types of the parameters in order after the name. Functions with variableargument lists are not supported. For other limitations, see the documentationon specific types.
new_callback(self, rettype, cbfunc, ...)
Creates a callback object which can be passed as a function pointer to a Cfunction. The arguments are the same as for get_function, except that insteadof a symbol name, a Lua function is passed. This function will then get calledwhen the C code calls through the function pointer. Because C/Invoke cannotcontrol the values being passed into and returned from the callbacks, thereare additional constraints on the types of arguments a callback can take; inparticular, arrays are not allowed as arguments.
It is highly reccomended to only use callbacks in circumstances where thepassed function pointer is called within the context of the C function, andnowhere 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 symbolin a shared library which points to a global C variable. Only basic types (notstrings, 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 functionadds a member to the structure. Once a function with the returned type isdeclared, a table value with the given name values as keys can be used torepresent an instance of this structure. Structures cannot be passed to Cfunctions by value; they must be passed in an array. Structures cannot containarrays 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")
联系客服