Next: Allocating Foreign Objects, Previous: Optimizing Type Translators, Up: Foreign Types [Contents][Index]
For more involved C types than simple aliases to built-in types, such
as you can make with defctype
, CFFI allows declaration of
structures and unions with defcstruct
and defcunion
.
For example, consider this fictional C structure declaration holding some personal information:
struct person { int number; char* reason; };
The equivalent defcstruct
form follows:
(defcstruct person
(number :int)
(reason :string))
By default, convert-from-foreign (and also mem-ref) will
make a plist with slot names as keys, and convert-to-foreign will
translate such a plist to a foreign structure. A user wishing to define
other translations should use the :class
argument to
defcstruct, and then define methods for
translate-from-foreign and
translate-into-foreign-memory that specialize on this class,
possibly calling call-next-method
to translate from and to the
plists rather than provide a direct interface to the foreign object.
The macro translation-forms-for-class
will generate the forms
necessary to translate a Lisp class into a foreign structure and vice
versa.
Please note that this interface is only for those that must know about
the values contained in a relevant struct. If the library you are
interfacing returns an opaque pointer that needs only be passed to
other C library functions, by all means just use :pointer
or a
type-safe definition munged together with defctype
and type
translation. To pass or return a structure by value to a function, load
the cffi-libffi system and specify the structure as (:struct
structure-name)
. To pass or return the pointer, you can use
either :pointer
or (:pointer (:struct
structure-name))
.
Compatibility note: Previous versions of CFFI accepted the
“bare” structure-name as a type specification, which was
interpreted as a pointer to the structure. This is deprecated and
produces a style warning. Using this deprecated form means that
mem-aref retains its prior meaning and returns a pointer. Using
the (:struct structure-name)
form for the type,
mem-aref provides a Lisp object translated from the
structure (by default a plist). Thus the semantics are consistent with all
types in returning the object as represented in Lisp, and not a pointer,
with the exception of the “bare” structure compatibility retained.
In order to obtain the pointer, you should use the function mem-aptr.
See defcstruct for more details.
Next: Allocating Foreign Objects, Previous: Optimizing Type Translators, Up: Foreign Types [Contents][Index]