CFFI依赖于某些功能

时间:2016-02-27 15:18:21

标签: common-lisp ffi chipmunk cffi

我正在使用CFFI在Chipmunk2d(2D物理模拟库)的Common Lisp上编写FFI。

当我评估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>)

打印输出来自我自己的翻译(见下文),但REPL永远不会返回。

我在Emacs 24.5,Mac OS X 10.10.5上使用Slime。 *inferior-lisp*上没有打印任何内容。

我尝试过CCL 1.11-r16635(DarwinX8664)和SBCL 1.2.0。当我在命令行上直接尝试sbcl时,行为是相同的。它挂了,没有调试器。

我做错了什么?

我测试了其他功能,它们运行良好:

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

这些是我定义的外国译员:

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

这些是我的函数定义:

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

0 个答案:

没有答案