Lisp HUG Maillist Archive

Lispworks FLI; Convert Lisp structs to C structs?

Does the :wrapper function provided by the Lispworks FLI provide the
capability to convert aggregate types (e.g. a lisp struct to a C struct)?

The example given in the Lispworks FLI documentation only describes passing an
integer from Lisp to C and back.




Re: Lispworks FLI; Convert Lisp structs to C structs?

Luke J Crook wrote:

>Does the :wrapper function provided by the Lispworks FLI provide the
>capability to convert aggregate types (e.g. a lisp struct to a C struct)?
>
>The example given in the Lispworks FLI documentation only describes passing an
>integer from Lisp to C and back.
>
>  
>

I do not think there is one built in, but you can build your own,...

for example

(in-package :cl-user)

(fli:define-c-struct c-pos
  (x :int)
  (y :int)
  (z :int))

(defstruct lisp-pos
  x
  y
  z)

(defun foreign-wrapper-function (foreign-struct-type)
  "Returns a Closure that allocates and initializes
   a foreign c struct from a lisp struct (or class)
   that has the same slot names."
  (lambda (lisp-slotted-object)
    (let ((c (fli:allocate-foreign-object :type foreign-struct-type)))
      (loop for slot-name in (fli:foreign-slot-names c)
            do (setf (fli:foreign-slot-value c slot-name)
                     (slot-value lisp-slotted-object slot-name)))
      c)))


CL-USER 1 > (defvar c-pos-wrapper (foreign-wrapper-function 'c-pos))
C-POS-WRAPPER

CL-USER 4 > (defvar c-pos (funcall c-pos-wrapper (make-lisp-pos :x 10 :y 
1243 :z 34)))
C-POS

CL-USER 5 > (describe c-pos)

#<Pointer to type (:STRUCT C-POS) = #x007C26C8> is a FLI::POINTER
POINTS-TO      #<Foreign-Structure (:STRUCT C-POS) : addr #x007C26C8>

CL-USER 6 > (loop for name in (fli:foreign-slot-names c-pos)
                  collect (cons name (fli:foreign-slot-value c-pos name)))
((X . 10) (Y . 1243) (Z . 34))

CL-USER 7 >

Reverse process to return a lisp struct/class from a foreign type.

Wade


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