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]