[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