[cffi-devel] trying to understand foreign types and translations

James Bielman jamesjb at jamesjb.com
Thu Jul 6 00:40:13 UTC 2006


rif <rif at MIT.EDU> writes:

> I have a foreign object, points to a vector of (C) double-floats:
>
> (defstruct (fnv-double (:constructor make-fnv-double-internal))
>   (foreign-pointer nil :read-only t)
>   (size 0 :type fixnum :read-only t))
>
> I can create and manipulate it.  I need to know how to define (with
> defcfun) an interface to a C function which expects a vector of
> double-floats.  My attempts have been along the lines of:
>
> (defmethod translate-to-foreign (val (f fnv-double)) (fnv-foreign-pointer f))

The two arguments to TRANSLATE-TO-FOREIGN are the Lisp object to be
converted, and the name of the foreign type to convert to.  First,
declare a foreign typedef for :POINTER (since you will ultimately be
returning a pointer from the type translator) that you use to hang
your type translator on:

(defctype fnv-double :pointer)

Then you can specialize TRANSLATE-TO-FOREIGN on both the Lisp value
and the foreign type (using an EQL specializer):

(defmethod translate-to-foreign ((value fnv-double) (name (eql 'fnv-double)))
  (fnv-foreign-pointer value))

It might be confusing to call both the Lisp and foreign types
FNV-DOUBLE, but it is legal because foreign type names are a separate
namespace from Lisp types (viva Lisp-N!).  It is important to remember
the distinction between the two though.

> and then declaring something like
>
> (defcfun ("foo" :%foo) :double
>    (x fnv-double))

should just work!

(This is untested and I haven't really been doing any CFFI hacking
lately, so I apologize if I missed something obvious here.)

James



More information about the cffi-devel mailing list