This defines a new CFFI aggregate type akin to C structs. 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:
- Simple
- Contain a single instance of a type that canonicalizes to a built-in type, such as :long or :pointer. Used for simple CFFI types.
- Aggregate
- Contain an embedded structure or union, or an array of objects. Used for aggregate 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.
Examples
(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))