[Convert docs to Texinfo format. Luis Oliveira **20050730160328] { hunk ./doc/cffi-sys-specification.html 1 - - - CFFI-SYS Specification - - - -

CFFI-SYS Interface Specfication

- -

Introduction

- -

- CFFI, the Common Foreign Function Interface, purports to be a - portable foreign function interface for Common Lisp. -

- -

- This specification defines a set of low-level primitives that - must be defined for each Lisp implementation supported by CFFI. - These operators are defined in the CFFI-SYS package. -

- -

- The CFFI package uses the CFFI-SYS interface - to implement an extensible foreign type system with support for - typedefs, structures, and unions, a declarative interface for - defining foreign function calls, and automatic conversion of - foreign function arguments to/from Lisp types. -

- -

Naming Convention

- -

- Functions in CFFI-SYS that are low-level versions of - functions exported from the CFFI package begin with a - leading percent-sign (eg. %mem-ref). -

- -

Built-In Foreign Types

- -

- Foreign Type: :char
- Foreign Type: :unsigned-char
- Foreign Type: :short
- Foreign Type: :unsigned-short
- Foreign Type: :int
- Foreign Type: :unsigned-int
- Foreign Type: :long
- Foreign Type: :unsigned-long
- Foreign Type: :long-long
- Foreign Type: :unsigned-long-long
-

- -

- These types correspond to the native C integer types according - to the ABI of the system the Lisp implementation is compiled - against. -

- -

- Foreign Type: :int8
- Foreign Type: :uint8
- Foreign Type: :int16
- Foreign Type: :uint16
- Foreign Type: :int32
- Foreign Type: :uint32
- Foreign Type: :int64
- Foreign Type: :uint64
-

- -

- Foreign integer types of specific sizes, corresponding to the C - types defined in stdint.h. -

- -

- Foreign Type: :size
- Foreign Type: :ssize
- Foreign Type: :ptrdiff
- Foreign Type: :time
-

- -

- Foreign integer types corresponding to the standard C types - (without the _t suffix). -

- -

- - I'm sure there are more of these that could be useful, let's - add any types that can't be defined portably to this list as - necessary. - -

- -

- Foreign Type: :float
- Foreign Type: :double
-

- -

- The :float type represents a C float and a Lisp - single-float. :double represents a - C double and a Lisp double-float. -

- -

Foreign Type: :pointer

- -

- A foreign pointer to an object of any type, corresponding to - void *. -

- -

Foreign Type: :void

- -

- No type at all. Only valid as the return type of a function. -

- -

Function: %foreign-type-size type => size

- -

- Return the size, in bytes, of objects having foreign type type. - An error is signalled if type is not a known built-in foreign - type. -

- -

Function: %foreign-type-alignment type => alignment

- -

- Return the default alignment in bytes for structure members of - foreign type type. An error is signalled if type - is not a known built-in foreign type. -

- -

- - Maybe this should take an optional keyword argument specifying - an alternate alignment system, eg. :mac68k for 68000-compatible - alignment on Darwin. - -

- -

Basic Pointer Operations

- -

Function: pointerp ptr => boolean

- -

- Return true if ptr is a foreign pointer. -

- -

Function: null-ptr => pointer

- -

- Return a null foreign pointer. -

- -

Function: null-ptr-p ptr => boolean

-

- Return true if ptr is a null foreign pointer. -

- -

Foreign Memory Allocation

- -

Function: foreign-alloc size => pointer

- -

- Allocate size bytes of foreign-addressable memory and - return a pointer to the allocated block. An - implementation-specific error is signalled if the memory cannot - be allocated. -

- -

Function: foreign-free ptr => unspecified

- -

- Free a pointer ptr allocated by foreign-alloc. - The results are undefined if ptr is used after being - freed. -

- -

Macro: with-foreign-ptr (var size - &optional size-var) &body body

- -

- Bind var to a pointer to size bytes of - foreign-accessible memory during body. Both ptr - and the memory block it points to have dynamic extent and may be - stack allocated if supported by the implementation. - If size-var is supplied, it will be bound to size - during body. -

- -

Memory Access

- -

Accessor: %mem-ref ptr type &optional (offset 0) => object

- -

- Dereference a pointer offset bytes from ptr to an - object for reading (or writing when used with setf) of - built-in type type. -

- -

Example: - -

-;; An impractical example, since 'time' returns the time as well, but it
-;; demonstrates %MEM-REF.  Better (simple) examples wanted!
-(with-foreign-ptr (p (foreign-type-size :time))
-  (foreign-funcall "time" :pointer p :time)
-  (%mem-ref p :time))
-
- -

Foreign Function Calling

- -

Macro: %foreign-funcall name - {arg-type arg}* &optional result-type - => object

- -

- Invoke a foreign function called name, which may be - mangled depending on the ABI of the system (eg. adding leading - underscore for Darwin). -

- -

- The remaining arguments are pairs of foreign types and their - values, followed by the return type of the function, assumed to - be :void if not supplied. -

- -

- - This wording is pretty awkward, rewrite this description. - -

- -

Examples:

- -
-;; Calling a standard C library function:
-(%foreign-funcall "sqrtf" :float 16.0 :float) => 4.0
-
-;; Dynamic allocation of a buffer and passing to a function:
-(with-foreign-ptr (buf 255 buf-size)
-  (%foreign-funcall "gethostname" :pointer buf :size buf-size :int)
-  ;; Convert BUF to a Lisp string using MAKE-STRING and %MEM-REF or a 
-  ;; portable CFFI function such as CFFI:LISP-STRING-FROM-FOREIGN.
-  )
-
- -

Loading Foreign Libraries

- -

Function: %load-foreign-library name => unspecified

- -

- Loads the foreign shared library name. -

- -

- - There is a lot of behavior to decide here. Currently I lean - toward not requiring NAME to be a full path to the library so - we can search the system library directories (maybe even get - LD_LIBRARY_PATH from the environment) as necessary. - -

- -

- - 6 June 2005 / James Bielman / jamesjb at jamesjb dot com - -

- - - rmfile ./doc/cffi-sys-specification.html hunk ./doc/manual.html 1 - - - CFFI User Manual - - - -

CFFI User Manual

- -

Introduction

- -

Motivation

- -

Design Philosophy

- - - -

Foreign Types

- -

Built-In Types

- -

- Foreign Type: :char
- Foreign Type: :unsigned-char
- Foreign Type: :short
- Foreign Type: :unsigned-short
- Foreign Type: :int
- Foreign Type: :unsigned-int
- Foreign Type: :long
- Foreign Type: :unsigned-long
- Foreign Type: :long-long
- Foreign Type: :unsigned-long-long
-

- -

- These types correspond to the native C integer types according to - the ABI of the system the Lisp implementation is compiled against. -

- -

- Foreign Type: :int8
- Foreign Type: :uint8
- Foreign Type: :int16
- Foreign Type: :uint16
- Foreign Type: :int32
- Foreign Type: :uint32
- Foreign Type: :int64
- Foreign Type: :uint64
-

- -

- Foreign integer types of specific sizes, corresponding to the C - types defined in stdint.h. -

- -

- Foreign Type: :size
- Foreign Type: :ssize
- Foreign Type: :ptrdiff
- Foreign Type: :time
-

- -

- Foreign integer types corresponding to the standard C types - (without the _t suffix). -

- -

- - I'm sure there are more of these that could be useful, let's - add any types that can't be defined portably to this list as - necessary. - -

- -

- Foreign Type: :float
- Foreign Type: :double
-

- -

- The :float type represents a C float and a Lisp - single-float. :double represents a - C double and a Lisp double-float. -

- -

Foreign Type: :pointer

- -

- A foreign pointer to an object of any type, corresponding to - void *. -

- -

Foreign Type: :void

- -

- No type at all. Only valid as the return type of a function. -

- -

Defining Typedefs

- -

- Macro: defctype name type - &optional documentation -

- -

Foreign Structure Types

- -

- Macro: defcstruct name &body - doc-options-and-slots -

- -

- A structure slot is either simple, or aggregate. -

- -

- Simple structure slots contain a single instance of a type that - canonicalizes to a built-in type, such as :long or - :pointer. -

- -

- Aggregate slots contain an embedded structure or union, or an array - of objects. -

- -

Example:

- -
-(defcstruct timeval
-  (tv-sec  :long)
-  (tv-usec :long))
-
- -

- Accessor: foreign-slot-value ptr type - &rest slot-names => object -

- -

- For simple slots, foreign-slot-value returns the value - of the object, such as a Lisp integer or pointer. In C, this - would be expressed as ptr->slot. -

- -

- For aggregate slots, a pointer inside the structure to the - beginning of the slot's data is returned. In C, this would be - expressed as - &ptr->slot. This pointer and the memory it points to - have the same extent as ptr. -

- -

- There are compiler macros for foreign-slot-value and its - setf expansion that open code the memory access when - type and slot-names are constant at compile-time. -

- -

- Macro: explain-foreign-slot-value ptr type - &rest slot-names -

- -

- This macro translates the slot access that would occur by calling - FOREIGN-SLOT-VALUE with the same arguments into an - equivalent expression in C and prints it - to *STANDARD-OUTPUT*. -

- -

Examples:

- -
-? (explain-foreign-slot-value ptr 'timeval 'tv-secs)
-ptr->tv_secs
-
-? (explain-foreign-slot-value emp 'employee 'hire-date 'tv-usecs)
-emp->hire_date.tv_usecs
-
- -

- Function: foreign-slot-pointer ptr type - &rest slot-names => ptr -

- -

- Returns a pointer to a slot referred to by slot-names - in a foreign object of type at ptr. The returned - pointer points inside the structure. Both the pointer and the - memory it points to have the same extent as ptr. -

- -

- For aggregate slots, this is the same value returned by - foreign-slot-value. -

- -

Foreign Structure Example

- -
-;; A hairy structure definition that illustrates some of the rules
-;; governing foreign structs.
-(defcstruct person
-  "A person in the employee database."
-  ;; the first argument after the name may be a docstring
-  :alignment :packed      ;; keyword options allowed before first slot
-  (id :int)
-  ;; these are defined as char[255]'s in the c code
-  (first-name  :char 255)
-  (last-name   :char 255)
-  ;; an embedded structure
-  (birthdate timeval)
-  ;; a pointer to another PERSON
-  (supervisor :pointer))
-
-;;; If P is a pointer to a PERSON structure:
-
-;; This returns p->first_name, a pointer.
-(foreign-slot-value p 'person 'first-name)
-
-;; This returns &p->birthdate, a pointer.
-(foreign-slot-value p 'person 'birthdate)
-
-;; This returns p->birthdate.tv_secs as a Lisp integer.
-(foreign-slot-value p 'person 'birthdate 'tv-secs)
-
-;; The previous form is equivalent to (but may be faster than):
-(foreign-slot-value
- (foreign-slot-value p 'person 'birthdate) 'timeval 'tv-secs)
-
-;; Attempting to set the slot value of an embedded structure or
-;; embedded array causes an error.  Eventually, there may be a
-;; type converter that can handle this situation for some types.
-;; This would be: p->birthdate = ... in C.
-(setf (foreign-slot-value p 'person 'timeval) ...) => error
-
- -

Operations on Types

- -

- Function: builtin-foreign-type-p type - => boolean -

- -

- Function: canonicalize-foreign-type type - => built-in-type -

- -

- Function: foreign-type-size size - => size -

- -

- Function: foreign-type-alignment type - => alignment -

- -

- Should these functions be part of the documented interface? They may - be useful for libraries built on top of CFFI---defining a type-safe - interface on top of CFFI pointers, for example. -

- -

Allocating Foreign Objects

- -

- Function: foreign-object-alloc type - &optional (count 1) => ptr -

- -
-(let ((ptr (foreign-object-alloc <type> <count>)))
-  ...)
-
-==>
-
-{
-   void *ptr = malloc (sizeof (<type>) * <count>);
-
-   if (ptr == NULL)
-      raise_storage_condition ();
-
-   ...
-}
-
- -

- Function: foreign-object-free ptr - => unspecified -

- -
-(foreign-object-free ptr)
-
-==>
-
-free (ptr);
-
- -

- Macro: with-foreign-object (var type - &optional (count 1)) &body body -

- -
-(with-foreign-object (ptr <type> <count>)
-  ...)
-
-==>
-
-{
-   void *ptr = alloca (sizeof (<type>) * <count>);
-   ...
-}
-
- -

Foreign Pointers

- -

- Describe the theory of how foreign variables work---they are always - pointers, even when accessing integer types or embedded structures. - You cannot represent a structure by value. -

- -

Basic Pointer Operations

- -

Allocating Foreign Memory

- -

Accessing Foreign Memory

- -

Foreign Strings

- -

Foreign Functions

- -

Calling Foreign Functions

- -

Defining Foreign Functions

- -

Foreign Type Translators

- -

- Example: -

- -
-;; Here is how the CFFI:BOOLEAN type translator is defined:
-(define-type-translator boolean :in (arg result-var)
-  "Type translator to convert t/nil to a C boolean."
-  (values `(if ,arg 1 0) nil))
-
-(define-type-translator boolean :result (arg result-var)
-  "Type translator to convert C booleans to t/nil."
-  (values `(if (zerop ,arg) nil t)))
-
- -

Foreign Libraries

- -

Limitiations

- -

- - 6 June 2005 / James Bielman / jamesjb at jamesjb dot com - -

- - rmfile ./doc/manual.html addfile ./doc/manual.texinfo hunk ./doc/manual.texinfo 1 +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename cffi.info +@settitle CFFI User Manual +@c %**end of header + +@c Show types in the same index as the functions. +@synindex tp fn + +@copying +Copyright @copyright{} 2005, James Bielman + +@quotation +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the ``Software''), to deal in the Software without +restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +@end quotation +@end copying + +@titlepage +@title CFFI User Manual +@c @subtitle Version X.X +@c @author James Bielman + +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@contents + +@ifnottex +@node Top +@top cffi +@insertcopying +@end ifnottex + +@menu +* Introduction:: +* Foreign Types:: +* Foreign Pointers:: +* Foreign Functions:: +* Foreign Libraries:: +* Limitations:: +* Symbol Index:: +@end menu + +@node Introduction +@chapter Introduction + +@section Motivation + +@section Design Philosophy + +@itemize +@item Pointers do not carry around type information. Instead, type + information is supplied when pointers are dereferenced. +@item A type safe pointer interface can be developed on top of an + untyped one. It is difficult to do the opposite. +@item Functions are better than macros. When a macro could be used + for performance, use a compiler-macro instead. +@end itemize + + +@node Foreign Types +@chapter Foreign Types + +@section Built-In Types + +@deftp {Foreign Type} :char +@end deftp +@deftp {Foreign Type} :unsigned-char +@end deftp +@deftp {Foreign Type} :short +@end deftp +@deftp {Foreign Type} :unsigned-short +@end deftp +@deftp {Foreign Type} :int +@end deftp +@deftp {Foreign Type} :unsigned-int +@end deftp +@deftp {Foreign Type} :long +@end deftp +@deftp {Foreign Type} :unsigned-long +@end deftp +@deftp {Foreign Type} :long-long +@end deftp +@deftp {Foreign Type} :unsigned-long-long +These types correspond to the native C integer types according to the +ABI of the system the Lisp implementation is compiled against. +@end deftp + +@deftp {Foreign Type} :int8 +@end deftp +@deftp {Foreign Type} :uint8 +@end deftp +@deftp {Foreign Type} :int16 +@end deftp +@deftp {Foreign Type} :uint16 +@end deftp +@deftp {Foreign Type} :int32 +@end deftp +@deftp {Foreign Type} :uint32 +@end deftp +@deftp {Foreign Type} :int64 +@end deftp +@deftp {Foreign Type} :uint64 +Foreign integer types of specific sizes, corresponding to the C types +defined in @code{stdint.h}. +@end deftp + +@deftp {Foreign Type} :size +@end deftp +@deftp {Foreign Type} :ssize +@end deftp +@deftp {Foreign Type} :ptrdiff +@end deftp +@deftp {Foreign Type} :time +Foreign integer types corresponding to the standard C types (without +the @code{_t} suffix). +@end deftp + +@emph{I'm sure there are more of these that could be useful, let's +add any types that can't be defined portably to this list as +necessary.} + +@deftp {Foreign Type} :float +@end deftp +@deftp {Foreign Type} :double +The @code{:float} type represents a C @code{float} and a Lisp +@code{single-float}. @code{:double} represents a C @code{double} and a +Lisp @code{double-float}. +@end deftp + +@deftp {Foreign Type} :pointer +A foreign pointer to an object of any type, corresponding to +@code{void *}. +@end deftp + +@deftp {Foreign Type} :void +No type at all. Only valid as the return type of a function. +@end deftp + +@section Defining Typedefs + +@defmac defctype name type &optional documentation +@end defmac + +@section Foreign Structure Types + +@defmac defcstruct name &body doc-options-and-slots +@end defmac + +A structure slot is either simple, or aggregate. + +Simple structure slots contain a single instance of a type that +canonicalizes to a built-in type, such as @code{:long} or +@code{:pointer}. + +Aggregate slots contain an embedded structure or union, or an array +of objects. + +@subsubheading Example: + +@lisp +(defcstruct timeval + (tv-sec :long) + (tv-usec :long)) +@end lisp + +@deffn {Accessor} foreign-slot-value ptr type &rest slot-names => object +For simple slots, @code{foreign-slot-value} returns the value of the +object, such as a Lisp integer or pointer. In C, this would be +expressed as @code{ptr->slot}. + +For aggregate slots, a pointer inside the structure to the beginning +of the slot's data is returned. In C, this would be expressed as +@code{&ptr->slot}. This pointer and the memory it points to have the +same extent as @code{ptr}. + +There are compiler macros for @code{foreign-slot-value} and its +@code{setf} expansion that open code the memory access when +@code{type} and @code{slot-names} are constant at compile-time. +@end deffn + +@defmac explain-foreign-slot-value ptr type &rest slot-names +This macro translates the slot access that would occur by calling +@code{FOREIGN-SLOT-VALUE} with the same arguments into an equivalent +expression in C and prints it to @code{*STANDARD-OUTPUT*}. +@end defmac + +@subsubheading Examples: + +@lisp +CFFI> (explain-foreign-slot-value ptr 'timeval 'tv-secs) +ptr->tv_secs + +CFFI> (explain-foreign-slot-value emp 'employee 'hire-date 'tv-usecs) +emp->hire_date.tv_usecs +@end lisp + +@defun foreign-slot-pointer ptr type &rest slot-names => pointer +Returns a pointer to a slot referred by @code{slot-names} in a foreign +object of type @code{type} at @code{ptr}. The returned pointer points +inside the structure. Both the pointer and the memory it points to +have the same extent as @code{ptr}. + +For aggregate slots, this is the same value returned by +@code{foreign-slot-value}. +@end defun + +@subheading Foreign Structure Example + +@lisp +;; A hairy structure definition that illustrates some of the rules +;; governing foreign structs. +(defcstruct person + "A person in the employee database." + ;; the first argument after the name may be a docstring + :alignment :packed ;; keyword options allowed before first slot + (id :int) + ;; these are defined as char[255]'s in the c code + (first-name :char 255) + (last-name :char 255) + ;; an embedded structure + (birthdate timeval) + ;; a pointer to another PERSON + (supervisor :pointer)) + +;;; If P is a pointer to a PERSON structure: + +;; This returns p->first_name, a pointer. +(foreign-slot-value p 'person 'first-name) + +;; This returns &p->birthdate, a pointer. +(foreign-slot-value p 'person 'birthdate) + +;; This returns p->birthdate.tv_secs as a Lisp integer. +(foreign-slot-value p 'person 'birthdate 'tv-secs) + +;; The previous form is equivalent to (but may be faster than): +(foreign-slot-value + (foreign-slot-value p 'person 'birthdate) 'timeval 'tv-secs) + +;; Attempting to set the slot value of an embedded structure or +;; embedded array causes an error. Eventually, there may be a +;; type converter that can handle this situation for some types. +;; This would be: p->birthdate = ... in C. +(setf (foreign-slot-value p 'person 'timeval) ...) => error +@end lisp + +@section Operations on Types + +@defun builtin-foreign-type-p type => boolean +@end defun + +@defun canonicalize-foreign-type type => built-in-type +@end defun + +@defun foreign-type-size type => size +@end defun + +@defun foreign-type-alignment type => alignment +@end defun + +@emph{Should these functions be part of the documented interface? They +may be useful for libraries built on top of CFFI---defining a type-safe +interface on top of CFFI pointers, for example.} + +@section Allocating Foreign Objects + +@defun foreign-object-alloc type &optional (count 1) => ptr +@end defun + +@lisp +(let ((ptr (foreign-object-alloc ))) + ...) + +==> + +@{ + void *ptr = malloc(sizeof() * ); + + if (ptr == NULL) + raise_storage_condition(); + + ... +@} +@end lisp + +@defun foreign-object-free ptr => unspecified +@end defun + +@lisp +(foreign-object-free ptr) + +==> + +free(ptr); +@end lisp + +@defmac with-foreign-object (var type &optional (count 1)) &body body +@end defmac + +@lisp +(with-foreign-object (ptr ) + ...) + +==> +@{ + void *ptr = alloca(sizeof() * ); + ... +@} +@end lisp + + +@node Foreign Pointers +@chapter Foreign Pointers + +@emph{Describe the theory of how foreign variables work---they are +always pointers, even when accessing integer types or embedded +structures. You cannot represent a structure by value.} + +@section Basic Pointer Operations + +@section Allocating Foreign Memory + +@section Accessing Foreign Memory + + +@node Foreign Functions +@chapter Foreign Functions + +@section Calling Foreign Functions + +@section Defining Foreign Functions + +@section Foreign Type Translators + +@subsubheading Example: + +@lisp +;; Here is how the CFFI:BOOLEAN type translator is defined: +(define-type-translator boolean :in (arg result-var) + "Type translator to convert t/nil to a C boolean." + (values `(if ,arg 1 0) nil)) + +(define-type-translator boolean :result (arg result-var) + "Type translator to convert C booleans to t/nil." + (values `(if (zerop ,arg) nil t))) +@end lisp + + +@node Foreign Libraries +@chapter Foreign Libraries + + +@node Limitations +@chapter Limitations + + +@node Symbol Index +@unnumbered Symbol Index +@printindex fn + +@bye addfile ./doc/spec.texinfo hunk ./doc/spec.texinfo 1 +\input texinfo @c -*-texinfo-*- +@c %**start of header£ +@setfilename cffi-sys.info +@settitle CFFI-SYS Interface Specification +@c %**end of header + +@c Show types in the same index as the functions. +@synindex tp fn + +@copying +Copyright @copyright{} 2005, James Bielman + +@quotation +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the ``Software''), to deal in the Software without +restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +@end quotation +@end copying + +@titlepage +@title CFFI-SYS Interface Specification +@c @subtitle Version X.X +@c @author James Bielman + +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@contents + +@ifnottex +@node Top +@top cffi-sys +@insertcopying +@end ifnottex + +@menu +* Introduction:: +* Built-In Foreign Types:: +* Operations on Foreign Types:: +* Basic Pointer Operations:: +* Foreign Memory Allocation:: +* Memory Access:: +* Foreign Function Calling:: +* Loading Foreign Libraries:: +* Symbol Index:: +@end menu + +@node Introduction +@chapter Introduction + +CFFI, the Common Foreign Function Interface, purports to be a portable +foreign function interface for Common Lisp. + +This specification defines a set of low-level primitives that +must be defined for each Lisp implementation supported by CFFI. +These operators are defined in the @code{CFFI-SYS} package. + +The @code{CFFI} package uses the @code{CFFI-SYS} interface +to implement an extensible foreign type system with support for +typedefs, structures, and unions, a declarative interface for +defining foreign function calls, and automatic conversion of +foreign function arguments to/from Lisp types. + +@subheading Naming Convention + +@noindent +Functions in @code{CFFI-SYS} that are low-level versions of +functions exported from the @code{CFFI} package begin with a +leading percent-sign (eg. @code{%mem-ref}). + +@node Built-In Foreign Types +@chapter Built-In Foreign Types + +@deftp {Foreign Type} :char +@end deftp +@deftp {Foreign Type} :unsigned-char +@end deftp +@deftp {Foreign Type} :short +@end deftp +@deftp {Foreign Type} :unsigned-short +@end deftp +@deftp {Foreign Type} :int +@end deftp +@deftp {Foreign Type} :unsigned-int +@end deftp +@deftp {Foreign Type} :long +@end deftp +@deftp {Foreign Type} :unsigned-long +@end deftp +@deftp {Foreign Type} :long-long +@end deftp +@deftp {Foreign Type} :unsigned-long-long +These types correspond to the native C integer types according to the +ABI of the system the Lisp implementation is compiled against. +@end deftp + +@deftp {Foreign Type} :int8 +@end deftp +@deftp {Foreign Type} :uint8 +@end deftp +@deftp {Foreign Type} :int16 +@end deftp +@deftp {Foreign Type} :uint16 +@end deftp +@deftp {Foreign Type} :int32 +@end deftp +@deftp {Foreign Type} :uint32 +@end deftp +@deftp {Foreign Type} :int64 +@end deftp +@deftp {Foreign Type} :uint64 +Foreign integer types of specific sizes, corresponding to the C types +defined in @code{stdint.h}. +@end deftp + +@deftp {Foreign Type} :size +@end deftp +@deftp {Foreign Type} :ssize +@end deftp +@deftp {Foreign Type} :ptrdiff +@end deftp +@deftp {Foreign Type} :time +Foreign integer types corresponding to the standard C types (without +the @code{_t} suffix). +@end deftp + +@emph{I'm sure there are more of these that could be useful, let's +add any types that can't be defined portably to this list as +necessary.} + +@deftp {Foreign Type} :float +@end deftp +@deftp {Foreign Type} :double +The @code{:float} type represents a C @code{float} and a Lisp +@code{single-float}. @code{:double} represents a C @code{double} and a +Lisp @code{double-float}. +@end deftp + +@deftp {Foreign Type} :pointer +A foreign pointer to an object of any type, corresponding to +@code{void *}. +@end deftp + +@deftp {Foreign Type} :void +No type at all. Only valid as the return type of a function. +@end deftp + + +@node Operations on Foreign Types +@chapter Operations on Built-in Foreign Types + +@defun %foreign-type-size type => size +Return the @code{size}, in bytes, of objects having foreign type +@code{type}. An error is signalled if @code{type} is not a known +built-in foreign type. +@end defun + +@defun %foreign-type-alignment type => alignment +Return the default alignment in bytes for structure members of foreign +type @code{type}. An error is signalled if @code{type} is not a known +built-in foreign type. + +@emph{Maybe this should take an optional keyword argument specifying an +alternate alignment system, eg. :mac68k for 68000-compatible alignment +on Darwin.} +@end defun + + +@node Basic Pointer Operations +@chapter Basic Pointer Operations + +@defun pointerp ptr => boolean +Return true if @code{ptr} is a foreign pointer. +@end defun + +@defun null-ptr => pointer +Return a null foreign pointer. +@end defun + +@defun null-ptr-p ptr => boolean +Return true if @code{ptr} is a null foreign pointer. +@end defun + + +@node Foreign Memory Allocation +@chapter Foreign Memory Allocation + +@defun foreign-alloc size => pointer +Allocate @code{size} bytes of foreign-addressable memory and return +a @code{pointer} to the allocated block. An implementation-specific +error is signalled if the memory cannot be allocated. +@end defun + +@defun foreign-free ptr => unspecified +Free a pointer @code{ptr} allocated by @code{foreign-alloc}. The +results are undefined if @code{ptr} is used after being freed. +@end defun + +@defmac with-foreign-ptr (var size &optional size-var) &body body +Bind @code{var} to a pointer to @code{size} bytes of +foreign-accessible memory during @code{body}. Both @code{ptr} and the +memory block it points to have dynamic extent and may be stack +allocated if supported by the implementation. If @code{size-var} is +supplied, it will be bound to @code{size} during @code{body}. +@end defmac + + +@node Memory Access +@chapter Memory Access + +@deffn {Accessor} %mem-ref ptr type &optional offset +Dereference a pointer @code{offset} bytes from @code{ptr} to an object +for reading (or writing when used with @code{setf}) of built-in type +@code{type}. +@end deffn + +@subsubheading Example: + +@lisp +;; An impratical example, since 'time' returns the time as well, +;; but it demonstrates %MEM-REF. Better (simple) examples wanted! +(with-foreign-ptr (p (foreign-type-size :time)) + (foreign-funcall "time" :pointer p :time) + (%mem-ref p :time)) +@end lisp + + +@node Foreign Function Calling +@chapter Foreign Function Calling + +@defmac %foreign-funcall name @{arg-type arg@}* &optional result-type => object +Invoke a foreign function called @code{name}, which may be mangled +depending on the ABI of the system (eg. adding leading underscore for +Darwin). + +The remaining arguments are pairs of foreign types and their values, +followed by the return type of the function, assumed to be +@code{:void} if not supplied. + +@emph{This wording is pretty awkward, rewrite this description.} +@end defmac + +@subsubheading Examples: + +@lisp +;; Calling a standard C library function: +(%foreign-funcall "sqrtf" :float 16.0 :float) => 4.0 +@end lisp + +@lisp +;; Dynamic allocation of a buffer and passing to a function: +(with-foreign-ptr (buf 255 buf-size) + (%foreign-funcall "gethostname" :pointer buf :size buf-size :int) + ;; Convert BUF to a Lisp string using MAKE-STRING and %MEM-REF or + ;; a portable CFFI function such as CFFI:LISP-STRING-FROM-FOREIGN. +) +@end lisp + + +@node Loading Foreign Libraries +@chapter Loading Foreign Libraries + +@defun %load-foreign-library name => unspecified +Loads the foreign shared library @code{name}. + +@emph{There is a lot of behavior to decide here. Currently I lean +toward not requiring NAME to be a full path to the library so +we can search the system library directories (maybe even get +LD_LIBRARY_PATH from the environment) as necessary.} +@end defun + +@node Symbol Index +@unnumbered Symbol Index +@printindex fn + +@bye addfile ./doc/style.css hunk ./doc/style.css 1 +body {font-family: century schoolbook, serif; + line-height: 1.3; + padding-left: 5em; padding-right: 1em; + padding-bottom: 1em; max-width: 60em;} +table {border-collapse: collapse} +span.roman { font-family: century schoolbook, serif; font-weight: normal; } +h1, h2, h3, h4, h5, h6 {font-family: Helvetica, sans-serif} +dfn {font-family: inherit; font-variant: italic; font-weight: bolder } +kbd {font-family: monospace; text-decoration: underline} +var {font-family: Helvetica, sans-serif; font-variant: slanted} +td {padding-right: 1em; padding-left: 1em} +sub {font-size: smaller} +.node {padding: 0; margin: 0} }