Loading Foreign Libraries
The FFI is normally used by extracting functions and other objects
from shared objects (a.k.a. shared libraries or
dynamically loaded libraries). The ffi-lib
function loads a shared object.
(ffi-lib path-or-false [version]) PROCEDURE
Returns an ffi-lib object. If path-or-false is a path
(or string), the result represents the foreign library, which is
opened in an OS-specific way (using LoadLibrary under Windows,
and dlopen under Unix and Mac OS X). The path is not expected to
contain the library suffix, which is added according to the current
platform. If adding the suffix fails, several other filename
variations are tried -- retrying without an automatically added
suffix, and using a full path of a file if it exists relative to the
current directory (since the OS-level library function usually
searches, unless the library name is an absolute path). An optional
version string can be supplied, which is appended to the name
after any added suffix. If you need any of a few possible versions,
use a list of version strings, and ffi-lib will try all of
them.
If path-or-false is #f, then the resulting
ffi-lib object represents all libraries loaded in the current
process, including libraries previouly opened with ffi-lib.
In particular, use #f to access C-level functionality
exported by the run-time system (as described in
Inside PLT MzScheme).
Note: ffi-lib tries to look for the library file in a few
places like the PLT libraries (see get-lib-search-dirs in the
setup collection), a relative path, or a system search.
However, if dlopen cannot open a library, there is no reliable
way to know why it failed, so if all path combinations fail, it will
raise an error with the result of dlopen on the unmodified
argument name. For example, if you have a local foo.so library
that cannot be loaded because of a missing symbol, using
(ffi-lib "foo.so") will fail with all its search options,
most because the library is not found, and once because of the missing
symbol, and eventually produce an error message that comes from
dlopen("foo.so") which will look like the file is not found. In
such cases try to specify a full or relative path (containing slashes,
e.g., ./foo.so).
Returns #t if v is the result of ffi-lib,
#f otherwise.
(get-ffi-obj objname lib type [failure-thunk]) PROCEDURE
Looks for the given object name objname (a string, a byte
string, or a symbol), in the given lib library (a library
object, string, path, or #f). If lib is not a library
object produced by ffi-lib, it is converted to one by calling
ffi-lib. If objname is found in lib, it is
converted to Scheme using the given type. Types are described in
the next chapter; in particular the get-ffi-obj procedure is
most often used with function types (see
section 3.5).
Keep in mind that get-ffi-obj is an unsafe procedure; see
Chapter 1 for details.
If the object is not found, and failure-thunk is provided, it is
used to produce a return value. For example, a failure thunk can be
provided to report a specific error if an object is not found:
(define foo
(get-ffi-obj "foo" foolib (_fun _int -> _int)
(lambda ()
(error 'foolib
"your installed foolib version does not provide \"foo\""))))
The default (also when failure-thunk is provided as #f) is to
raise an exception
(set-ffi-obj! objname lib type new) PROCEDURE
Looks for the objname in lib similarly to get-ffi-obj, but
then it stores the given new value into the library, converting it to a C
value. This can be used for setting library customization variables that are
part of its interface, including Scheme callbacks.
(make-c-parameter objname lib ctype) PROCEDURE
Returns a parameter-like procedure that can either reference the specified foreign value, or set it. This is useful in case Scheme code and library code interact through a library value. It can be used with any type, but it is not recommended to use this for foreign functions since each reference through this will construct the low-level interface before the actual call.
( SYNTAX
define-c var lib type)
This syntax uses make-c-parameter above: it defines a var
syntax that behaves like a Scheme binding, referencing and setting it is
achieved through such a C parameter (so the same comments apply). The
var part is used both for the Scheme binding and for the foreign object's
name.
(ffi-obj-ref objname lib) FAILURE-THUNK
procedure
Returns a pointer object for the required foreign object. This is for rare
cases where make-c-parameter is insufficient because there is no type
to cast the foreign object to (e.g., a vector of numbers).