Pointers Common Lisp CFFI:指向指针的指针

Pointers Common Lisp CFFI:指向指针的指针,pointers,common-lisp,cffi,Pointers,Common Lisp,Cffi,我正在尝试为库编写CFFI包装器。SWIG被日晷的标题堵住了,因为它们相互连接,SWIG找不到正确的标题,所以我用手做了:有点费力,但我成功了 现在我正在测试它是否正常工作。现在,只需创建“问题对象”并将其删除即可。问题就从这里开始。因此,“问题对象”是通过函数分配的 SUNDIALS_EXPORT void *CVodeCreate(int lmm, int iter); 我为其创建了包装器: (cffi:defcfun "CVodeCreate" :pointer (lmm :int)

我正在尝试为库编写CFFI包装器。SWIG被日晷的标题堵住了,因为它们相互连接,SWIG找不到正确的标题,所以我用手做了:有点费力,但我成功了

现在我正在测试它是否正常工作。现在,只需创建“问题对象”并将其删除即可。问题就从这里开始。因此,“问题对象”是通过函数分配的

SUNDIALS_EXPORT void *CVodeCreate(int lmm, int iter);
我为其创建了包装器:

(cffi:defcfun "CVodeCreate" :pointer
  (lmm :int)
  (iter :int))
PS.
Sundails\u导出(至少在Unix上)基本上什么都不是

现在,为了摧毁该物体,日晷使用它自己的功能:

SUNDIALS_EXPORT void CVodeFree(void **cvode_mem);
(cffi:defcfun "CVodeFree" :void
  (cvode-mem :pointer))
因此,我需要将引用传递给由
CVodeCreate
创建的对象。在C语言中,如果我的内存没有问题,我会做类似于
CVodeFree(&problem\u object)
的事情。在CL中,我为函数编写了以下包装:

SUNDIALS_EXPORT void CVodeFree(void **cvode_mem);
(cffi:defcfun "CVodeFree" :void
  (cvode-mem :pointer))
因此,这里的
COVDE-MEM
是指向指针的指针。问题是如何获取CL/CFFI中指针的指针?以下是代码的开头:

(defvar *p* (cvodecreate 1 2))
(注:不要担心传递给
CVODECREATE
的数字,它们只是告诉要使用哪些方法,仍然需要定义常量以使其更具可读性)

因此,
*p*
类似于

#.(SB-SYS:INT-SAP #X7FFFE0007060)
如果我将其直接传递给
CVODEFREE
,它最终会出错:

CL-USER> (cvodefree *p*)
; Evaluation aborted on #<SIMPLE-ERROR "bus error at #X~X" {1005EC9BD3}>.

这是可行的(至少不会抛出错误)。我想我理解了它的工作原理:它创建(分配内存)一个指向一个指针的指针
P
,其
MEM-REF
(或者用C术语来说是去引用
*P
)由
CVODECREATE
上的结果填充。最后,我将这个指针传递给
CVODEFREE
,这正是我所期望的。最后,一旦表单完成,为
P
分配的内存将被释放。这是正确的方法吗?这是我唯一可以采用的方法吗?

是的,你的方法看起来不错,下面是一个小测试,展示了可以直接从repl运行的概念

(let* (;; a float
       (v0 32s0)

       ;; a pointer to a float foreign memory
       (p0 (cffi:foreign-alloc :float :initial-element v0))) 

  ;; a new pointer
  (cffi:with-foreign-object (p1 :pointer)

    ;; make the new pointer point to the first pointer
    (setf (cffi:mem-aref p1 :pointer) p0)

    ;; dereferencing twice should give you the original number
    (cffi:mem-aref (cffi:mem-aref p1 :pointer) :float)))

p、 我相信你现在已经知道了,很抱歉花了这么长时间才给你一个答案。希望这能对其他人有所帮助

如果知道他们为什么选择了
CVodeFree
的签名,会非常有趣。看起来像是“过度工程化”并试图变得更加聪明。@DanielJour就我记忆所及,这种方式在C世界中并不罕见。也许,它们会释放内存并在那里将指针设为空。但我同意,这完全没有必要。
memaref
确实有帮助。谢谢