7

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

0 に答える 0