27.11.2014 Views

CFFI User Manual - Common Lisp.net

CFFI User Manual - Common Lisp.net

CFFI User Manual - Common Lisp.net

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Chapter 6: Foreign Types 24<br />

:boolean &optional (base-type :int)<br />

[Foreign Type]<br />

The :boolean type converts between a <strong>Lisp</strong> boolean and a C boolean. It canonicalizes<br />

to base-type which is :int by default.<br />

(convert-to-foreign nil :boolean) ⇒ 0<br />

(convert-to-foreign t :boolean) ⇒ 1<br />

(convert-from-foreign 0 :boolean) ⇒ nil<br />

(convert-from-foreign 1 :boolean) ⇒ t<br />

:wrapper base-type &key to-c from-c<br />

[Foreign Type]<br />

The :wrapper type stores two symbols passed to the to-c and from-c arguments. When<br />

a value is being translated to or from C, this type funcalls the respective symbol.<br />

:wrapper types will be typedefs for base-type and will inherit its translators, if any.<br />

Here’s an example of how the :boolean type could be defined in terms of :wrapper.<br />

(defun bool-c-to-lisp (value)<br />

(not (zerop value)))<br />

(defun bool-lisp-to-c (value)<br />

(if value 1 0))<br />

(defctype my-bool (:wrapper :int :from-c bool-c-to-lisp<br />

:to-c bool-lisp-to-c))<br />

(convert-to-foreign nil ’my-bool) ⇒ 0<br />

(convert-from-foreign 1 ’my-bool) ⇒ t<br />

6.3 Defining Foreign Types<br />

You can define simple C-like typedefs through the defctype macro. Defining a typedef is<br />

as simple as giving defctype a new name and the name of the type to be wrapped.<br />

;;; Define MY-INT as an alias for the built-in type :INT.<br />

(defctype my-int :int)<br />

With this type definition, one can, for instance, declare arguments to foreign functions<br />

as having the type my-int, and they will be passed as integers.<br />

More complex types<br />

<strong>CFFI</strong> offers another way to define types through define-foreign-type, a thin wrapper<br />

macro around defclass. As an example, let’s go through the steps needed to define a<br />

(my-string &key encoding) type. First, we need to define our type class:<br />

(define-foreign-type my-string-type ()<br />

((encoding :reader string-type-encoding :initarg :encoding))<br />

(:actual-type :pointer))<br />

The :actual-type class option tells <strong>CFFI</strong> that this type will ultimately be passed to and<br />

received from foreign code as a :pointer. Now you need to tell <strong>CFFI</strong> how to parse a type<br />

specification such as (my-string :encoding :utf8) into an instance of my-string-type.<br />

We do that with define-parse-method:

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!