RE: Passing lisp vector to foreign code
Sorry, I should mention that the ffi definition for get_bytes is
(fli:define-foreign-function
(get-bytes "get_bytes" :source)
((db db)
(nbytes (:reference-return :int)))
:result-type (:pointer (:unsigned :char))
:lambda-list (db &aux nbytes)
:calling-convention :cdecl)
-----Original Message-----
From: Young, David [mailto:deyoung@bloodhoundinc.com]
Sent: Friday, July 29, 2005 10:38 AM
To: 'Martin Simmons'
Cc: lisp-hug@lispworks.com
Subject: RE: Passing lisp vector to foreign code
However, I got a suggestion to look at fli:replace-foreign-array. The
following code gives me this error:
Error: Attempting to get address of non string or signed-byte/unsigned-byte
vector: SIMPLE-VECTOR.
1 (abort) Return to level 0.
2 Return to top loop level 0.
Type :b for backtrace, :c <option number> to proceed, or :? for other
options
Here's the revised code:
(defmethod fill-stream-buffer ((self binary-input-stream) db)
(with-slots ((buf buffer)
(len bufsiz)) self
(multiple-value-bind (bytes nbytes)
(get-bytes db)
(let ((buf (make-array nbytes)))
(fli:replace-foreign-array buf bytes)
(setf len nbytes)))))
I've also tried (make-array nbytes :element-type 'unsigned-byte).
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.
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.