name-and-options ::= structure-name | (structure-name &key size)
doc-and-slots ::= [docstring] { (slot-name slot-type &key count offset) }*
1
as such an array and a single element
are semantically equivalent.
This defines a new CFFI aggregate type akin to C struct
s.
In other words, it specifies that foreign objects of the type
structure-name are groups of different pieces of data, or
“slots”, of the slot-types, distinguished from each other by
the slot-names. Each structure is located in memory at a
position, and the slots are allocated sequentially beginning at that
point in memory (with some padding allowances as defined by the C
ABI, unless otherwise requested by specifying an
offset from the beginning of the structure (offset 0).
In other words, it is isomorphic to the C struct
, giving
several extra features.
There are two kinds of slots, for the two kinds of CFFI types:
:long
or :pointer
. Used for simple
CFFI types.
The use of CLOS terminology for the structure-related features is intentional; structure definitions are very much like classes with (far) fewer features.
(defcstruct point "Point structure." (x :int) (y :int)) CFFI> (with-foreign-object (ptr 'point) ;; Initialize the slots (setf (foreign-slot-value ptr 'point 'x) 42 (foreign-slot-value ptr 'point 'y) 42) ;; Return a list with the coordinates (with-foreign-slots ((x y) ptr point) (list x y))) => (42 42)
;; Using the :size and :offset options to define a partial structure. ;; (this is useful when you are interested in only a few slots ;; of a big foreign structure) (defcstruct (foo :size 32) "Some struct with 32 bytes." ; <16 bytes we don't care about> (x :int :offset 16) ; an int at offset 16 (y :int) ; another int at offset 16+sizeof(int) ; <a couple more bytes we don't care about> (z :char :offset 24)) ; a char at offset 24 ; <7 more bytes ignored (since size is 32)> CFFI> (foreign-type-size 'foo) => 32
;;; Using :count to define arrays inside of a struct. (defcstruct video_tuner (name :char :count 32))