Pointers Common Lisp CFFI:指向指针的指针
我正在尝试为库编写CFFI包装器。SWIG被日晷的标题堵住了,因为它们相互连接,SWIG找不到正确的标题,所以我用手做了:有点费力,但我成功了 现在我正在测试它是否正常工作。现在,只需创建“问题对象”并将其删除即可。问题就从这里开始。因此,“问题对象”是通过函数分配的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)
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
确实有帮助。谢谢