Next: , Previous: Functions, Up: Functions


defcfun

Syntax

— Macro: defcfun name-and-options return-type &body [docstring] arguments [&rest] ⇒ lisp-name

name-and-options ::= name | (name &key library convention)
name ::= lisp-name [foreign-name] | foreign-name [lisp-name]
arguments ::= { (arg-name arg-type) }*

Arguments and Values

foreign-name
A string denoting a foreign function.
lisp-name
A symbol naming the Lisp function to be created.
arg-name
A symbol.
return-type
arg-type
A foreign type.
convention
One of :cdecl (default) or :stdcall.
library
A symbol designating a foreign library.
docstring
A documentation string.

Description

The defcfun macro provides a declarative interface for defining Lisp functions that call foreign functions.

When one of lisp-name or foreign-name is omitted, the other is automatically derived using the following rules:

If you place the symbol &rest in the end of the argument list after the fixed arguments, defcfun will treat the foreign function as a variadic function. The variadic arguments should be passed in a way similar to what foreign-funcall would expect. Unlike foreign-funcall though, defcfun will take care of doing argument promotion. Note that in this case defcfun will generate a Lisp macro instead of a function and will only work for Lisps that support foreign-funcall.

If a foreign structure is to be passed or returned by value (that is, the type is of the form (:struct ...)), then the cffi-libffi system must be loaded, which in turn depends on libffi, including the header files. Failure to load that system will result in an error. Variadic functions cannot at present accept or return structures by value.

Examples

  (defcfun "strlen" :int
    "Calculate the length of a string."
    (n :string))
   
  CFFI> (strlen "123")
  => 3
  (defcfun ("abs" c-abs) :int (n :int))
   
  CFFI> (c-abs -42)
  => 42

Function without arguments:

  (defcfun "rand" :int)
   
  CFFI> (rand)
  => 1804289383

Variadic function example:

  (defcfun "sprintf" :int
    (str :pointer)
    (control :string)
    &rest)
   
  CFFI> (with-foreign-pointer-as-string (s 100)
          (sprintf s "%c %d %.2f %s" :char 90 :short 42 :float pi
                   :string "super-locrian"))
  => "A 42 3.14 super-locrian"

See Also

foreign-funcall
foreign-funcall-pointer