Package: cffi

Macro defcfun

Lambda List

defcfun (name-and-options return-type &body args)

Syntax

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

Arguments

foreign-name -- A string denoting a foreign function.
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.

Return Value

A symbol naming the Lisp function to be created.

Details

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:
  • Foreign names are converted to Lisp names by uppercasing and replacing underscores with hyphens.
  • Lisp names are converted to foreign names by lowercasing and replacing hyphens with underscores.
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.

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