The Dynamic Library Loader (DynLib) module allows Falcon applications to load dynamic link libraries, or shared objects on UNIX systems, and use the functions as if it were standard Falcon functions.
This release is an alpha release for final 1.0 version. The module is released for testing purposes and to allow a wider user base to test it.
In particular, all the functions in the Structure Support group are being reorganized and moved in the Core module. Part of their functionalities is already available under other names and usage patterns.
In this version the following features scheduled for 1.0 are missing:
This module has two goals:
The load and configure operations are nearly free with respect to load and VM-link a full Falcon binding, and calling a dynamic function requires approximately the same time needed to call an external function bound in a module.
The cost of choosing to use DynLib instead of an official Falcon module lays mainly in three factors:
\note The DynLib module allows to run foreign code that may not respect the rules under which code controlled by the virtual machine and the Falcon scripting engine enforce on binary modules. Even slight misusage may cause unpredictable crashes.
The DynLib module exposes mainly three entities:
Once loaded a library, it is possible to load DynFunction searching its prototype. For example:
load dynlib lib = DynLib( "/usr/lib/checksum.so" ) // or your favorite library func = lib.get( "int checksum( const char* str, int len )" ) teststr = "Hello world" > @'CKSUM of "$teststr": ', func( teststr, teststr.len() )
The type signatures supported by dynlib are all the C types, with optional pointer, array subscript and const signatures. The module takes care of checking for the congruency of the parameters against the declared type signature. More about type conversions are describe in the DynFunction reference.
Many libraries use a pointer to a structure or to a union as a kind of object that is manipulated by various functions in the library, and finally disposed through a specific free function. Falcon provides support for those pseudo types so that they can be seen as opaque variables (whose content can actually be inspected, if necessary), and eventually automatically freed via the Falcon garbage collector.
When the return value is a pointer to a structure or a union, Falcon returns an instance of a DynOpaque object, storing the returned data, meta-informations about its original name and type, and eventually a reference to a free function to be called when the object goes out of scope. For example:
load dynlib lib = DynLib( "make_data.dll" ) // or your favorite library func = lib.get( "struct Value* createMe( int size )", // creator function "void freeValue( struct Value* v )" // destructor function ) value = func( 1500 ) ... ...
It is possible to call also functions with variable parameter prototype by using the "..." symbol, like in the following example:
load dynlib stdc = DynLib( "/lib/libc.so.6" ) printf = stdc.get( "void printf( const char* format, ... )" ) printf( "Hello %s\n", "world" )
In this case, as the DynLib can't use the declared parameter types as a guide to determine how to convert the input parameters, some rigid Falcon-item-to-C transformations are applied.
Other types are not allowed.