<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><br></div><div><br></div><div><br></div><div><br></div><br><div><div>On Sep 12, 2010, at 1:57 PM, Gustavo wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Actually, there is documentation, it's linked in CFFI's main page:<div><a href="http://common-lisp.net/gitweb?p=projects/cffi/cffi.git;a=blob_plain;f=doc/shareable-vectors.txt">http://common-lisp.net/gitweb?p=projects/cffi/cffi.git;a=blob_plain;f=doc/shareable-vectors.txt</a></div></blockquote><div><blockquote type="cite"><div>You seem to need to use CFFI:MAKE-SHAREABLE-BYTE-VECTOR to create the array.</div></blockquote></div><div><br></div><div>I saw this, but I assumed it was just a proposal, plus</div><div>the use of shared vectors makes it hard to use with most lisp data, often leading the same</div><div>copying overhead that would have arisen just malloc'ing.</div><div><br></div><div>I've been passing arrays to foreign libraries for a long time. I used to think that the right</div><div>solution was to pass the Lisp data itself. Sometimes, for huge arrays on a 32 bit machine,</div><div>it was actually necessary. Now, however, I've concluded that simply copying to malloc is good the </div><div>vast majority of the time. There might be some truth to the adage that the perfect is the </div><div>enemy of the good.</div><div><br></div><div><br></div><div>At any rate, I've put my WAAF copying package here: </div><div><br></div><div> <a href="http://www.cliki.net/WAAF-CFFI">http://www.cliki.net/WAAF-CFFI</a></div><div> <a href="http://sites.google.com/site/lithpthtuff/home/waaf-cffi">http://sites.google.com/site/lithpthtuff/home/waaf-cffi</a></div><div><br></div><div>JK</div><div><br></div><div><br></div><div><br></div><br><blockquote type="cite">
<div><br></div><div><a href="http://common-lisp.net/gitweb?p=projects/cffi/cffi.git;a=blob_plain;f=doc/shareable-vectors.txt"></a><br><br><div class="gmail_quote">
Em 12 de setembro de 2010 20:39, Gustavo <span dir="ltr"><<a href="mailto:gugamilare@gmail.com">gugamilare@gmail.com</a>></span> escreveu:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Hello,<div><br></div><div>What about CFFI:WITH-POINTER-TO-VECTOR-DATA? Or did you just miss it? Documentation is missing, but it pines the array within its body (which means the array won't be moved, but garbage collector might still run) and grabs the foreign pointer of the array, at least on SBCL.</div>
<div><br></div><div>Regards,</div><div>Gustavo.</div><div><br><div class="gmail_quote">2010/9/11 JTK <span dir="ltr"><<a href="mailto:jetmonk@gmail.com" target="_blank">jetmonk@gmail.com</a>></span><div><div></div>
<div class="h5"><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
Hello,<br>
<br>
I'm using cffi, and I need to perform the common task of passing Lisp arrays to foreign code.<br>
<br>
This task comes up a lot in scientific code, matrix math, image processing, etc.<br>
<br>
Normally, it involves a lot of boilerplate to allocate a pointer, copy data Lisp to foreign<br>
memory, copy the data back, and deallocate the memory. Getting the copying to run<br>
fast can be tricky.<br>
<br>
Hence I wrote a package to automate it. It maintains a set of specialized copying<br>
functions to copy from array of Lisp type X to foreign memory of type Y. On SBCL, copying<br>
doesn't cons and is reasonably fast (~200 MB a second, there and back)<br>
<br>
I've put the package here:<br>
<br>
<a href="http://www.megaupload.com/?d=CX1XFMU6" target="_blank">http://www.megaupload.com/?d=CX1XFMU6</a><br>
<br>
Sorry for the megaupload, and its imposed delay, but I didn't want to spam the list with a 100K file.<br>
<br>
The package includes a MANUAL.txt and a test package.<br>
<br>
I'd be happy to have this included in a user contrib section of CFFI, if the maintainers<br>
think it would be useful.<br>
<br>
<br>
<br>
<br>
Here's an example the main macro does:<br>
<br>
<br>
(LET ((U (MAKE-ARRAY 100 :ELEMENT-TYPE 'SINGLE-FLOAT :INITIAL-ELEMENT 1.0)))<br>
;;<br>
(WITH-ARRAY-AS-FOREIGN-POINTER<br>
(U PU :FLOAT ;; LISP-VAR POINTER-VAR CFFI-FOREIGN-TYPE<br>
:LISP-TYPE SINGLE-FLOAT ;; promise U is a single-float array<br>
:START 2 ;; begin at index 2 of of Lisp array<br>
:END 7 ;; last index used is 6<br>
:COPY-TO-FOREIGN T ;; put contents of Lisp into foreign memory<br>
:COPY-FROM-FOREIGN T) ;; copy back from FFI space to lisp array<br>
;;<br>
;; at this point, PU is a foreign pointer containing data copied<br>
;; from the array starting at element 1 and ending at 6, of type :FLOAT.<br>
<br>
(SOME-FOREIGN-FUNCTION PU))<br>
;;<br>
;; at end, all foreign memory is deallocated, and U has been copied<br>
;; back from foreign space, but the 0th element of U is untouched<br>
;; because START was 1, not 0<br>
)<br>
<br>
<br>
-John<br>
_______________________________________________<br>
cffi-devel mailing list<br>
<a href="mailto:cffi-devel@common-lisp.net" target="_blank">cffi-devel@common-lisp.net</a><br>
<a href="http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel" target="_blank">http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel</a><br>
</blockquote></div></div></div><br></div>
</blockquote></div><br></div>
</blockquote></div><br></body></html>