[Cffi-devel] FSBV question

Liam Healy lnp at healy.washington.dc.us
Fri Apr 18 19:23:29 UTC 2014


My first cut at this makes me think that the translate-from-foreign and
w-f-o should trade places. Here's a selected macroexpansion of GSLL's
cx-add:

(LET ()
  (DEFUN CX-ADD (C1 C2)
    (DECLARE)
    (LET ((#:CRETURN
           (WITH-FOREIGN-OBJECT (#:G1705 '(:STRUCT GRID:COMPLEX-DOUBLE-C))
             (TRANSLATE-INTO-FOREIGN-MEMORY C1
                                            #<GRID::COMPLEX-DOUBLE-TYPE
                                              GRID:COMPLEX-DOUBLE-C>
                                            #:G1705)
             (WITH-FOREIGN-OBJECT (#:G1706 '(:STRUCT GRID:COMPLEX-DOUBLE-C))
               (TRANSLATE-INTO-FOREIGN-MEMORY C2
                                              #<GRID::COMPLEX-DOUBLE-TYPE
                                                GRID:COMPLEX-DOUBLE-C>
                                              #:G1706)
               (TRANSLATE-FROM-FOREIGN   ;;;   <=========== this should be
after the next two lines
                (WITH-FOREIGN-OBJECTS ((CFFI::ARGVALUES :POINTER 2)
                                       (CFFI::RESULT '(:STRUCT
GRID:COMPLEX-DOUBLE-C)))
                  (LOOP :FOR CFFI::ARG :IN (LIST #:G1705 #:G1706)
                        :FOR
                        COUNT :FROM 0
                        :DO (SETF (MEM-AREF CFFI::ARGVALUES :POINTER COUNT)
CFFI::ARG))
                  (CFFI::CALL
                   (CFFI::PREPARE-FUNCTION "gsl_complex_add"
                                           '(:STRUCT GRID:COMPLEX-DOUBLE-C)
                                           '((:STRUCT GRID:COMPLEX-DOUBLE-C)
                                             (:STRUCT
GRID:COMPLEX-DOUBLE-C))
                                           ':DEFAULT-ABI)
                   (FOREIGN-SYMBOL-POINTER "gsl_complex_add") CFFI::RESULT
CFFI::ARGVALUES)
                  CFFI::RESULT)
                #<GRID::COMPLEX-DOUBLE-TYPE GRID:COMPLEX-DOUBLE-C>)))))
      #:CRETURN))
  (MAP-NAME 'CX-ADD "gsl_complex_add")
  (EXPORT 'CX-ADD))

So that means some mashing around the other definitions, as the
translate-from-foreign comes in outside the ffcall-body-libffi. As to why
it works in SBCL (and maybe CCL): um, luck?

Liam



On Fri, Apr 18, 2014 at 2:01 PM, Cyrus Harmon <ch-lisp at bobobeach.com> wrote:

>
> So I've been trying to get FSBV working on ABCL and I've run into a
> problem with returning structs. The problem is that we allocate memory on
> the stack for the return struct, successfully call the foreign function,
> writing the return value into the appropriate place, then we free the
> memory and return a pointer to the now defunct memory location.
>
> I'm curious as to how this is supposed to work in other implementations.
> It obviously does work in, at least, SBCL, so I must be doing something
> wrong. But looking at the ffcall-body-libffi function it looks like we
> setup the foreign memory for RESULT in with-foreign-objects and then if we
> have a translatable-foreign-type, we return RESULT, which of course gets
> freed by with-foreign-objects. What am I missing here?
>
> thanks,
>
> Cyrus
>
>
> (defun ffcall-body-libffi
>     (function symbols return-type argument-types &optional pointerp (abi
> :default-abi))
>   "A body of foreign-funcall calling the libffi function #'call
> (ffi_call)."
>   (let ((number-of-arguments (length argument-types)))
>     `(with-foreign-objects
>          ((argvalues :pointer ,number-of-arguments)
>           ,@(unless (eql return-type :void)
>               `((result ',return-type))))
>        (loop :for arg :in (list , at symbols)
>              :for count :from 0
>              :do (setf (mem-aref argvalues :pointer count) arg))
>        (call
>         (prepare-function ,function ',return-type ',argument-types ',abi)
>         ,(if pointerp
>              function
>              `(foreign-symbol-pointer ,function))
>         ,(if (eql return-type :void) '(null-pointer) 'result)
>         argvalues)
>        ,(if (eql return-type :void)
>             '(values)
>             (if (typep (parse-type return-type) 'translatable-foreign-type)
>                 ;; just return the pointer so that expand-from-foreign
>                 ;; can apply translate-from-foreign
>                 'result
>                 ;; built-in types won't be translated by
>                 ;; expand-from-foreign, we have to do it here
>                 `(mem-aref result ',return-type))))))
> _______________________________________________
> Cffi-devel mailing list
> Cffi-devel at common-lisp.net
> http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/cffi-devel/attachments/20140418/73f40ee4/attachment.html>


More information about the cffi-devel mailing list