LispWorks Foreign Language Interface User Guide and Reference Manual > 5 Function and Macro Reference

NextPrevUpTopContentsIndex

define-c-struct

Macro
Summary

Defines a FLI structure type specifier corresponding to the C struct type.

Package

fli

Signature

define-c-struct name-and-options &rest descriptions => list

name-and-options ::= name | ( name option *)

option ::= (:foreign-name string )

descriptions ::= { slot-description | byte-packing }*

slot-description ::= { slot-name | ( slot-name slot-type )}

byte-packing ::= (:byte-packing nbytes )

nbytes ::= integer

Arguments

name

A symbol naming the new structure type specifier

string

A string specifying the foreign name of the structure.

slot-description

A symbol, or a list of symbol and type description, naming a slot in the structure

slot-name

A symbol naming the slot

slot-type

The foreign type of the slot

byte-packing

A list specifying byte packing for the subseqent slots

nbyte s

The number of 8-bit bytes to pack

Values

list

The list (:struct name )

Description

The macro define-c-struct is used to define a FLI structure type specifier, which corresponds to the C struct type. It is a convenience function, as a structure type could also be defined using define-foreign-type.

A structure is an aggregate type, or collection, of other FLI types. The types contained in a structure are referred to as slots, and can be accessed using the define-foreign-type and foreign-slot-value functions.

Some C compilers support pragmas such as

#pragma pack(1)

which causes fields in a structure to be aligned on a byte boundary even if their natural alignment is larger. This can be achieved from Lisp by specifying suitable byte-packing forms in the structure definition, as in the example below. Each byte-packing form specifies the packing for each slot-description that follows it in the define-c-struct form. It is important to use the same packing as the C header file containing the foreign type.

Example

The first example shows a C structure definition and the corresponding FLI definition:

struct a-point {
  int x;
  int y;
  byte color;
  char ident;
};
 
(fli:define-c-struct a-point (x :int)
                             (y :int)
                             (color :byte)
                             (ident :char))

The second example shows how you might retrieve data in Lisp from a C function that returns a structure:

struct 3dvector
{
 float x;
 float y;
 float z;
 }
 
static 3dvector* vector;
 
3dvector* fn ()
{
 return vector;
 }
 
(fli:define-c-struct 3dvector
  (x :float)
  (y :float)
  (z :float))
 
(fli:define-foreign-function fn ()
  :result-type (:pointer (:struct 3dvector)))
 
(let ((vector (fn)))
  (fli:with-foreign-slots (x y z) vector
    (values x y z)))

Finally an example to illustrate byte packing. This structure will require 4 bytes of memory because the field named a-short will be aligned on a 2 byte boundary and hence a byte will be wasted after the a-byte field:

(fli:define-c-struct foo ()
  (a-byte (:unsigned :byte))
  (a-short (:unsigned :short)))

After adding the byte-packing form, the structure will require only 3 bytes:

(fli:define-c-struct foo
  (:byte-packing 1)
  (a-byte (:unsigned :byte))
  (a-short (:unsigned :short)))
See also

define-c-enum
define-c-typedef
define-c-union
define-foreign-type
foreign-slot-names
foreign-slot-type
foreign-slot-value


LispWorks Foreign Language Interface User Guide and Reference Manual - 21 Dec 2009

NextPrevUpTopContentsIndex