[cffi-devel] defcstruct and array.

Luis Oliveira luismbo at gmail.com
Wed Dec 31 02:04:24 UTC 2008


mosi <amosat+python at gmail.com> writes:

> (defcstruct point
>   (nr :int)
>   (name :char :count 32)
>   (coordinates :float :count 3))
[...]
> but how do I read the array of floats with N dimensions into lisp?

The array functionality that CFFI currently exports is pretty
low-level. Here's one way to do it:

  (with-foreign-slots ((coordinates) ptr point)
    ;; the COORDINATES slot is a pointer to the array, which
    ;; can be dereferenced through MEM-AREF.
    (loop for i below 3
          collect (mem-aref coordinates :float i)))
   => (1.0 2.0 3.0)

There has been some work on a higher-level interface, but it's currently
unexported and unsupported (i.e. the interface may change in a backwards
incompatible way). Here's an example:

  (with-foreign-slots ((coordinates) ptr point)
    ;; again, COORDINATES is a pointer.
    (cffi::foreign-array-to-lisp coordinates '(:array :float 3)))
  => #(1.0 2.0 3.0)

We can make it a little more high-level (hacked this in just now and
commited to the darcs repository, so if you want to try it, you need to
darcs pull, since :ARRAY wasn't working properly for structs):

  (defcstruct another-point
    (nr :int)
    (name (:array :char 32))
    (coordinates (:array :float 3)))

  (foreign-slot-value ptr 'another-point 'coordinates) => #(1.0 2.0 3.0)

I suppose it'd be even better if DEFCSTRUCT defined some
accessors. (IIRC, this has been suggested before.) Then you could
simply use:

  (point-coordinates ptr) => #(1.0 2.0 3.0)

Oh what the heck. :-) Hacked that in as well:

  (defcstruct (point :conc-name point-)
    (nr :int)
    (name (:array :char 32))
    (coordinates (:array :float 3)))

  (with-foreign-object (p 'point)
    (setf (point-coordinates p) #(3.0 2.0 1.0))
    (point-coordinates p))
  => #(3.0 2.0 1.0)

I hope that's useful, but keep in mind that this functionality is
undocumented, unexported and unsupported. :-) Suggestions for some name
better than :CONC-NAME are welcome!

-- 
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/





More information about the cffi-devel mailing list