Hello,
I'm using cffi, and I need to perform the common task of passing Lisp arrays to foreign code.
This task comes up a lot in scientific code, matrix math, image processing, etc.
Normally, it involves a lot of boilerplate to allocate a pointer, copy data Lisp to foreign memory, copy the data back, and deallocate the memory. Getting the copying to run fast can be tricky.
Hence I wrote a package to automate it. It maintains a set of specialized copying functions to copy from array of Lisp type X to foreign memory of type Y. On SBCL, copying doesn't cons and is reasonably fast (~200 MB a second, there and back)
I've put the package here:
http://www.megaupload.com/?d=CX1XFMU6
Sorry for the megaupload, and its imposed delay, but I didn't want to spam the list with a 100K file.
The package includes a MANUAL.txt and a test package.
I'd be happy to have this included in a user contrib section of CFFI, if the maintainers think it would be useful.
Here's an example the main macro does:
(LET ((U (MAKE-ARRAY 100 :ELEMENT-TYPE 'SINGLE-FLOAT :INITIAL-ELEMENT 1.0))) ;; (WITH-ARRAY-AS-FOREIGN-POINTER (U PU :FLOAT ;; LISP-VAR POINTER-VAR CFFI-FOREIGN-TYPE :LISP-TYPE SINGLE-FLOAT ;; promise U is a single-float array :START 2 ;; begin at index 2 of of Lisp array :END 7 ;; last index used is 6 :COPY-TO-FOREIGN T ;; put contents of Lisp into foreign memory :COPY-FROM-FOREIGN T) ;; copy back from FFI space to lisp array ;; ;; at this point, PU is a foreign pointer containing data copied ;; from the array starting at element 1 and ending at 6, of type :FLOAT.
(SOME-FOREIGN-FUNCTION PU)) ;; ;; at end, all foreign memory is deallocated, and U has been copied ;; back from foreign space, but the 0th element of U is untouched ;; because START was 1, not 0 )
-John