Previous Section | Next Section | Table of Contents | Glossary | Index |
CCL
provides a number of constructs for calling
foreign functions from Lisp code (all of them based on the
function CCL:%FF-CALL). In many cases, CCL
's interface
translator (see ) provides information about the foreign
function's entrypoint name and argument and return types; this
enables the use of the #_ reader macro (described below),
which may be more concise and/or more readable than other
constructs.
CCL
also provides a mechanism for defining
callbacks: lisp functions which can be
called from foreign code.
There's no supported way to directly pass lisp data to foreign functions: scalar lisp data must be coerced to an equivalent foreign representation, and lisp arrays (notably strings) must be copied to non-GCed memory.
The types of foreign argument and return values in foreign function calls and callbacks can be specified by any of the following keywords:
The argument/return value is of type (UNSIGNED-BYTE 8)
The argument/return value is of type (SIGNED-BYTE 8)
The argument/return value is of type (UNSIGNED-BYTE 16)
The argument/return value is of type (SIGNED-BYTE 16)
The argument/return value is of type (UNSIGNED-BYTE 32)
The argument/return value is of type (SIGNED-BYTE 32)
The argument/return value is of type (UNSIGNED-BYTE 64)
The argument/return value is of type (SIGNED-BYTE 64)
The argument/return value is of type SINGLE-FLOAT
The argument/return value is of type DOUBLE-FLOAT
The argument/return values is a MACPTR.
or NIL Not valid as an argument type specifier; specifies that there is no meaningful return value
On some platforms, a small positive integer N can also be used as an argument specifier; it indicates that the corresponding argument is a pointer to an N-word structure or union which should be passed by value to the foreign function. Exactly which foreign structures are passed by value and how is very dependent on the Application Binary Interface (ABI) of the platform; unless you're very familiar with ABI details (some of which are quite baroque), it's often easier to let higher-level constructs deal with these details.
PowerPC machine instructions are always aligned on
32-bit boundaries, so the two least significant bits of the
first instruction ("entrypoint") of a foreign function are
always 0. CCL
often represents an entrypoint address as
a fixnum that's binary-equivalent to the entrypoint address:
if E is an entrypoint address expressed
as a signed 32-bit integer, then (ash E
-2) is an equivalent fixnum representation of that
address. An entrypoint address can also be encapsulated in a
MACPTR (see FIXTHIS), but that's somewhat less efficient.
Although it's possible to use fixnums or macptrs to
represent entrypoint addresses, it's somewhat cumbersome to
do so. CCL
can cache the addresses of named external
functions in structure-like objects of type
CCL:EXTERNAL-ENTRY-POINT (sometimes abbreviated as EEP).
Through the use of LOAD-TIME-VALUE, compiled lisp functions
are able to reference EEPs as constants; the use of an
indirection allows CCL
runtime system to ensure that the
EEP's address is current and correct.
On some platforms, C functions that are defined to return structures do so by reference: they actually accept a first parameter of type "pointer to returned struct/union" - which must be allocated by the caller - and don't return a meaningful value.
Exactly how a C function that's defined to return a foreign structure does so is dependent on the ABI (and on the size and composition of the structure/union in many cases.)
Previous Section | Next Section | Table of Contents | Glossary | Index |