All Manuals > LispWorks Foreign Language Interface User Guide and Reference Manual > 2 FLI Types


2.2 Aggregate types

Aggregate types are types such as arrays, strings and structures. The internal structure of an aggregate type is not transparent in the way that immediate types are. For example, two structures may have the same size of 8 bytes, but one might partition its bytes into two integers, whereas the other might be partitioned into a byte, an integer, and another byte. The FLI provides a number of functions to manipulate aggregate types. A feature of aggregate types is that they are usually accessed through the use of pointers, rather than directly.

2.2.1 Arrays

The FLI has two predefined array types: the :c-array type, which corresponds to C arrays, and the :foreign-array type. The two types are the same in all aspects but one: if you attempt to pass a :c-array by value through a foreign function, the starting address of the array is what is actually passed, whereas if you attempt to pass a :foreign-array in this manner, an error is raised.

For examples on the use of FLI arrays refer to :c-array and :foreign-array in Type Reference.

2.2.2 Strings

The FLI provides two foreign types to interface Lisp and C strings, :ef-wc-string and :ef-mb-string.

The :ef-mb-string converts between a Lisp string and an external format C multi-byte string. A maximum number of bytes must be given as a limit for the string size.

The :ef-wc-string converts between a Lisp string and an external format C wide character string. A maximum number of characters must be given as a limit for the string size.

For more information on converting Lisp strings to foreign language strings see the string types :ef-mb-string, :ef-wc-string, and the string functions convert-from-foreign-string, convert-to-foreign-string, and with-foreign-string.

2.2.3 Structures and unions

The FLI provides the :struct and :union types to interface Lisp objects with the C struct and union types.

To define types to interface with C structures, the FLI macro define-c-struct is provided. In the next example it is used to define a FLI structure, tagpoint:

(fli:define-c-struct tagpoint 
  (x :long) 
  (y :long)
  (visible (:boolean :byte))

This structure would interface with the following C structure:

typedef struct tagPOINT {
    LONG x; 
    LONG y; 
    BYTE visible;

The various elements of a structure are known as slots, and can be accessed using the FLI foreign slot functions foreign-slot-names, foreign-slot-type and foreign-slot-value, and the macro with-foreign-slots. For example, the next commands set point equal to an instance of tagPOINT, and set the Lisp variable names equal to a list of the names of the slots of tagPOINT.

(setq point (fli:allocate-foreign-object :type 'tagpoint)) (setq names (fli:foreign-slot-names point))

The next command finds the type of the first element in the list names, and sets the variable name-type equal to it.

(setq name-type (fli:foreign-slot-type point (car names)))

Finally, the following command sets point-to equal to a pointer to the first element of point, with the correct type.

(setq point-to (fli:foreign-slot-pointer point (car names) 
                                        :type name-type))

The above example demonstrates some of the functions used to manipulate FLI structures. The FLI :union type is similar to the :struct type, in that the FLI slot functions can be used to access instances of a union. The convenience FLI function define-c-union is also provided for the definition of specific union types.

LispWorks Foreign Language Interface User Guide and Reference Manual - 16 Feb 2015