Common Lisp:Cffi:Setf'ing a Foreign Type

时间:2012-12-20 21:32:40

标签: common-lisp ffi

我最近一直在玩这个梦幻般的cffi,但是如果使用内置机制可以实现某些功能,我就会遇到问题。

我想创建一个外部矢量数组,并设置外部类型转换,以便这样做。

> (defparameter a (foreign-alloc 'vec3 :count 10))
A
> (setf (mem-aref  a 'vec3 4) (convert-to-foreign #(1.0 2.0 3.0) 'vec3))
#(1.0 2.0 3.0)
> (convert-from-foreign (mem-aref b 'vec3 4) 'vec3)
#(1.0 2.0 3.0

到目前为止,我有以下内容允许创建和获取外部vec3,但不允许检索。

(defcstruct %vec3
  (components :float :count 3))

(define-foreign-type vec3-type ()
  ()
  (:actual-type %vec3)
  (:simple-parser vec3))

(defmethod translate-from-foreign (value (type vec3-type))
  (make-array 
   3 
   :element-type 'single-float
   :initial-contents (list (mem-aref value :float 0)
               (mem-aref value :float 1)
               (mem-aref value :float 2))))

问题在于,虽然我可以很容易地设置一个函数作为vec3的设置器,但我希望有一些建立的方式可以做到这一点,我只是没有看到。我已经阅读了cffi手册并且已经看到了翻译到外来的方法以及扩展到外来的dyn,但我还没有找到一种方法来使用它来实质上扩展到如下所示:

(let ((tmp (mem-aref a '%vec3 4)))
  (setf (mem-aref tmp :float 0) (aref lisp-value 0))
  (setf (mem-aref tmp :float 1) (aref lisp-value 1))
  (setf (mem-aref tmp :float 2) (aref lisp-value 2)))

这样就不会分配额外的内存,而是直接设置值。

那是我的小白日梦,有人知道它是否可以起作用吗?

1 个答案:

答案 0 :(得分:0)

读过CFFI源代码,似乎内置机制不支持这一点。那里有用于处理数组类型的代码,但它没有公开或导出,因此显然不能使用。还有一个建议的块存储器接口,但尚未编写。

这次没有骰子,但是CFFI很棒,所以我只是以不同的方式制作它。

P.S。还有WAAF-CFFI值得研究,但我还没有具体细节