Next: ffi-curl, Previous: Examining and Modifying, Up: Foreign Functions [Contents][Index]
As usual in most libraries written in C, objects carry an abstract type. These abstract types can be aliases for the built-in ones, ‘struct’s or ‘union’s composed by more atomic types.
For the bare aliasing of types, there is a macro
define-ffi-type
, which can also be used to construct unions, as
well as arrays.
Associate name with FFI type. When defining global
structures or unions, name may be nil
, in that case
name is derived from the name of type.
(define-ffi-type mytype unsigned-long) ⇒ mytype
Once a type is defined that way, it can be used as if it was a native C-type.
(ffi-type-p 'mytype) ⇒ t (ffi-size-of-type 'mytype) ⇒ 4
As mentioned above, we look at the construction of arrays now.
(define-ffi-type myarray (array unsigned-long 8)) ⇒ myarray (ffi-size-of-type 'myarray) ⇒ 32
Similarly, unions and structs can be defined. For structs, however,
there exists a more dedicated definition function,
define-ffi-struct
. This function also defines setter and
getter forms which can be used to selectively set or get the slots in
a structure.
Getting the value of a slot in a structure defined that way can be
done with a function structname->slotname
. Setting
values is achieved by using setf
on
structname->slotname
.
Define a new structure of NAME and SLOTS.
(define-ffi-struct foo (sl1 unsigned-int) (sl2 char) (sl3 int)) ⇒ (lambda (obj) " Common Lisp lambda list: (foo->sl3 OBJ) " (block foo->sl3 (let* ((--obj--temp-- (gensym "--obj--")) (--nv--temp-- (gensym "--nv--"))) (list (list --obj--temp--) (list obj) (list --nv--temp--) (let* ((obj --obj--temp--) (nv --nv--temp--)) (list (quote ffi-store) obj (list (quote ffi-slot-offset) (quote (quote foo)) (quote (quote sl3))) (list (quote ffi-slot-type) (quote (quote foo)) (quote (quote sl3))) nv)) (list (quote foo->sl3) --obj--temp--))))) (fboundp #'foo->sl1) ⇒ t (fboundp #'foo->sl2) ⇒ t (fboundp #'foo->sl2) ⇒ t
A special case of user-defined data are so called enumerations. Basically they are used to simultaneously define a large block of aliases. These are enumerated (beginning from 0) and are replaced by the according integers during the preprocessor time.
For convenience the SXEmacs FFI interface provides a similar functionality.
Define an enumeration name. Optional argument docstring is a documentation string.
specs can be an arbitrary number of symbols which will be enumerated in the respective order.
Additionally the cells of specs may look like
‘ foo = bar’
to adhere a symbol ‘foo’ to the enumeration with the value of the symbol ‘bar’ (i.e. ‘foo’ is an alias of ‘bar’).
Moreover, it is possible to set the counter explicitly:
‘ baz = 5’
would assign a value of 5 to the symbol ‘baz’ and (by side-effect) set the counter to 6 for the next symbol.
The defined enumeration will result in a (defconst
’d) variable
name
, the value is an alist of the form
‘ ((symbol . value) ...)’,
where ‘value’ is the C-value of ‘symbol’.
Furthermore, two functions (named name
and
name-value
) will be defined. The first one is a simple
lookup function returning the C-value of a passed symbol. The second
does basically the same but returns the representing (elisp) integer of
a symbol. Both functions return nil
if the symbol is not in the
enumeration.
Next: ffi-curl, Previous: Examining and Modifying, Up: Foreign Functions [Contents][Index]