Lisp HUG Maillist Archive

RE: Passing lisp vector to foreign code

Thanks. Here's how I got it working:

Outbound:

(let ((buf (output-buffer self))
      (bufsiz (buffer-size self)))
  (fli:with-dynamic-foreign-objects ()
    (let ((vector (fli:allocate-dynamic-foreign-object :type `(:c-array
(:unsigned :char) ,bufsiz))))
      (dotimes (i bufsiz)
        (setf (fli:foreign-aref vector i) (aref buf i)))
      (put-bytes db vector bufsiz)

Inbound:

with-slots ((buf buffer)
             (len bufsiz)) self
  (multiple-value-bind (bytes nbytes)
      (get-bytes db)
    (let ((contents (loop for i from 0 below nbytes collect (fli:dereference
bytes :index i))))
      (setf buf (make-array nbytes :initial-contents contents))
      (setf len (length buf)))))

Look reasonable?

dey

-----Original Message-----
From: Martin Simmons [mailto:martin@lispworks.com]
Sent: Thursday, July 28, 2005 1:10 PM
To: deyoung@bloodhoundinc.com
Cc: lisp-hug@lispworks.com
Subject: Re: Passing lisp vector to foreign code


>>>>> On Wed, 27 Jul 2005 11:26:44 -0400, "Young, David"
<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
buffer and
  dey> send it to a C function, which stores it in a "database". Later, I
want to
  dey> retrieve this data via another binary stream class (we're
experimenting with
  dey> CL-STORE). Using the lw ffi, how do I set this up? It seems from the
docs
  dey> that I need to make a copy of the buffer in static space prior to
sending it
  dey> to C; is that correct? What should the ffi function declarations look
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> so clearly I'm doing something wrong. Thanks for the help.

There are two kinds of static array: Lisp and foreign.  The :C-ARRAY foreign
type needs a foreign array object (e.g. created with
FLI:ALLOCATE-FOREIGN-OBJECT).  See also the :LISP-ARRAY foreign type if you
want to pass a static Lisp array pointer directly to C.

-- 
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

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.


Re: Passing lisp vector to foreign code

|     (let ((contents (loop for i from 0 below nbytes collect
(fli:dereference
| bytes :index i))))
|       (setf buf (make-array nbytes :initial-contents contents))
|       (setf len (length buf)))))
|
| Look reasonable?

Check out fli:replace-foreign-array which is much faster than that loop.

Paul



Re: Passing lisp vector to foreign code

Unable to parse email body. Email id is 4252

Updated at: 2020-12-10 08:51 UTC