[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