I'm writing a FFI on Common Lisp for Chipmunk2d (a 2D physics simulation library) using CFFI.
When I evaluate on the REPL:
> (cp:moment-for-circle 100 0 1 #(0 0))
(translate-into-foreign-memory 100 #<CL-CHIPMUNK-CFFI::CP-FLOAT-TYPE #x30200199A54D> #<A Foreign Pointer [stack-allocated] #xB136CD80>)
(translate-to-foreign 100.0D0 #<CL-CHIPMUNK-CFFI::CP-FLOAT-TYPE #x30200198793D>)
(translate-into-foreign-memory 0 #<CL-CHIPMUNK-CFFI::CP-FLOAT-TYPE #x30200199A50D> #<A Foreign Pointer [stack-allocated] #xB136CD40>)
(translate-to-foreign 0.0D0 #<CL-CHIPMUNK-CFFI::CP-FLOAT-TYPE #x30200198793D>)
(translate-into-foreign-memory 1 #<CL-CHIPMUNK-CFFI::CP-FLOAT-TYPE #x30200199A4CD> #<A Foreign Pointer [stack-allocated] #xB136CD00>)
(translate-to-foreign 1.0D0 #<CL-CHIPMUNK-CFFI::CP-FLOAT-TYPE #x30200198793D>)
(translate-into-foreign-memory #(0 0) #<VECT-TYPE CL-CHIPMUNK-CFFI::VECT> #<A Foreign Pointer [stack-allocated] #xB136CCC0>)
The printed output comes from my own translators (see below), but the REPL never returns.
I'm using Slime on Emacs 24.5, Mac OS X 10.10.5. There is nothing printed on *inferior-lisp*
.
I've tried with CCL 1.11-r16635 (DarwinX8664) and SBCL 1.2.0. When I try directly on sbcl on the command line, the behaviour is the same. It hangs, and there's no debugger.
What am I doing wrong?
I have tested other functions, and they work fine:
> (cp:circle-shape-new *static-body* 1 #(0 0))
(translate-into-foreign-memory 1 #<CL-CHIPMUNK-CFFI::CP-FLOAT-TYPE #x30200198FCDD> #<A Foreign Pointer [stack-allocated] #xB136CD40>)
(translate-to-foreign 1.0D0 #<CL-CHIPMUNK-CFFI::CP-FLOAT-TYPE #x30200198793D>)
(translate-into-foreign-memory #(0 0) #<VECT-TYPE CL-CHIPMUNK-CFFI::VECT> #<A Foreign Pointer [stack-allocated] #xB136CD00>)
#<A Foreign Pointer #x10C440>
> (cp:moment-for-box 100 10 20)
(translate-to-foreign 100 #<CL-CHIPMUNK-CFFI::CP-FLOAT-TYPE #x3020019999FD>)
(translate-to-foreign 10 #<CL-CHIPMUNK-CFFI::CP-FLOAT-TYPE #x3020019999BD>)
(translate-to-foreign 20 #<CL-CHIPMUNK-CFFI::CP-FLOAT-TYPE #x30200199997D>)
4166.666666666667D0
These are the foreign translators I defined:
(define-foreign-type cp-float-type ()
()
(:actual-type :double)
(:simple-parser cp-float))
(defmethod translate-to-foreign (float (type cp-float-type))
"Ensures that a Lisp float is of type double."
(format t "(translate-to-foreign ~S ~S)~%" float type)
(call-next-method (coerce float 'double-float) type))
(defmethod translate-into-foreign-memory (float (type cp-float-type) ptr)
(format t "(translate-into-foreign-memory ~S ~S ~S)~%" float type ptr)
(setf (mem-ref ptr 'cp-float) (coerce float 'double-float)))
;; typedef struct cpVect{cpFloat x,y;} cpVect;
(defcstruct (vect :class vect-type)
(x :double)
(y :double))
(defmethod translate-from-foreign (vect (type vect-type))
(format t "(translate-from-foreign ~S ~S)~%" vect type)
(let ((plist (call-next-method)))
(vector (getf plist 'x) (getf plist 'y))))
(defmethod translate-into-foreign-memory (vect (type vect-type) ptr)
(format t "(translate-into-foreign-memory ~S ~S ~S)~%" vect type ptr)
(setf (foreign-slot-value ptr '(:struct vect) 'x) (coerce (elt vect 0) 'double-float)
(foreign-slot-value ptr '(:struct vect) 'y) (coerce (elt vect 1) 'double-float)))
These are my function definitions:
;; cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);
(defcfun ("cpMomentForCircle" moment-for-circle) cp-float
(m cp-float)
(r1 cp-float)
(r2 cp-float)
(offset (:struct vect)))
;; cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);
(defcfun ("cpMomentForBox" moment-for-box) cp-float
(m cp-float)
(width cp-float)
(height cp-float))
;; cpShape* cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);
(defcfun ("cpCircleShapeNew" circle-shape-new) :pointer
(body :pointer)
(radius cp-float)
(offset (:struct vect)))
CFFI-libffi
loaded? – Soot