RE: Passing lisp vector to foreign code
get_bytes is allocated by C from memory that is stable until the next call, so that part is ok. dey -----Original Message----- From: Martin Simmons [mailto:martin@lispworks.com] Sent: Thursday, July 28, 2005 4:08 PM To: deyoung@bloodhoundinc.com Cc: lisp-hug@lispworks.com Subject: Re: Passing lisp vector to foreign code >>>>> On Thu, 28 Jul 2005 13:15:16 -0400, "Young, David" <deyoung@bloodhoundinc.com> said: dey> Thanks. Here's how I got it working: dey> Outbound: dey> (let ((buf (output-buffer self)) dey> (bufsiz (buffer-size self))) dey> (fli:with-dynamic-foreign-objects () dey> (let ((vector (fli:allocate-dynamic-foreign-object :type `(:c-array dey> (:unsigned :char) ,bufsiz)))) dey> (dotimes (i bufsiz) dey> (setf (fli:foreign-aref vector i) (aref buf i))) dey> (put-bytes db vector bufsiz) dey> Inbound: dey> with-slots ((buf buffer) dey> (len bufsiz)) self dey> (multiple-value-bind (bytes nbytes) dey> (get-bytes db) dey> (let ((contents (loop for i from 0 below nbytes collect (fli:dereference dey> bytes :index i)))) dey> (setf buf (make-array nbytes :initial-contents contents)) dey> (setf len (length buf))))) dey> Look reasonable? What allocates the memory returned by get-bytes and should something free it? -- Martin Simmons Email: martin@lispworks.com LispWorks Ltd, St John's Innovation Centre TEL: +44 1223 421860 Cowley Road, Cambridge CB4 0WS, England. FAX: +44 870 2206189 dey> -----Original Message----- dey> From: Martin Simmons [mailto:martin@lispworks.com] dey> Sent: Thursday, July 28, 2005 1:10 PM dey> To: deyoung@bloodhoundinc.com dey> Cc: lisp-hug@lispworks.com dey> Subject: Re: Passing lisp vector to foreign code >>>>> On Wed, 27 Jul 2005 11:26:44 -0400, "Young, David" dey> <deyoung@bloodhoundinc.com> said: dey> So, I have a binary stream class that collects bytes into a buffer dey> represented by a vector with a fill pointer. I want to take this dey> buffer and dey> send it to a C function, which stores it in a "database". Later, I dey> want to dey> retrieve this data via another binary stream class (we're dey> experimenting with dey> CL-STORE). Using the lw ffi, how do I set this up? It seems from the dey> docs dey> that I need to make a copy of the buffer in static space prior to dey> sending it dey> to C; is that correct? What should the ffi function declarations look dey> like? dey> Currently, I have: dey> (fli:define-foreign-function dey> (put-bytes "put_bytes" :source) dey> ((bytes (:c-array (:unsigned :char))) dey> (len :int)) dey> :result-type :void dey> :calling-convention :cdecl) dey> (fli:define-foreign-function dey> (get-bytes "get_bytes" :source) dey> ((nbytes (:pointer (:int)))) dey> :result-type (:c-array (:unsigned :char)) dey> :calling-convention :cdecl) dey> But, passing a Lisp vector to PUT-BYTES yields a type error: dey> Expecting type (:foreign-array (:UNSIGNED :CHAR) (0)) (got #(76 dey> ...)) dey> so clearly I'm doing something wrong. Thanks for the help. dey> There are two kinds of static array: Lisp and foreign. The :C-ARRAY foreign dey> type needs a foreign array object (e.g. created with dey> FLI:ALLOCATE-FOREIGN-OBJECT). See also the :LISP-ARRAY foreign type if you dey> want to pass a static Lisp array pointer directly to C. dey> -- dey> Martin Simmons Email: martin@lispworks.com dey> LispWorks Ltd, St John's Innovation Centre TEL: +44 1223 421860 dey> Cowley Road, Cambridge CB4 0WS, England. FAX: +44 870 2206189 This email message is for the sole use of the intended recipients(s) and may contain confidential and privileged information of Bloodhound Software, Inc.. Any unauthorized review, use, disclosure is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.