首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通用Lisp :指向指针的指针

通用Lisp :指向指针的指针
EN

Stack Overflow用户
提问于 2016-03-07 10:48:11
回答 1查看 1.4K关注 0票数 6

我正在尝试为日晷CVODE库编写CFFI包装器。SWIG被Sundials的头卡住了,因为它们是相互关联的,但是没有找到正确的标题,所以我手工完成了它:有点辛苦,但我已经成功了。

现在我试着测试它是否正确。现在,只需创建"problem对象“并删除它。这就是问题开始的地方。因此,通过函数分配“问题对象”。

代码语言:javascript
复制
SUNDIALS_EXPORT void *CVodeCreate(int lmm, int iter);

为此我创建了包装器:

代码语言:javascript
复制
(cffi:defcfun "CVodeCreate" :pointer
  (lmm :int)
  (iter :int))

PS。SUNDIALS_EXPORT (至少在Unix上)基本上是没有意义的。

现在,为了销毁这个对象,Sundials使用了它自己的功能:

代码语言:javascript
复制
SUNDIALS_EXPORT void CVodeFree(void **cvode_mem);

因此,我需要将引用传递给CVodeCreate创建的对象。在C语言中,如果我的内存不是错误的,我就会做一些类似CVodeFree(&problem_object)的事情。在CL中,我为函数编写了这个包装器:

代码语言:javascript
复制
(cffi:defcfun "CVodeFree" :void
  (cvode-mem :pointer))

因此,这里COVDE-MEM是指向指针的指针。问题是如何在CL/CFFI中得到指针?下面是代码的开头:

代码语言:javascript
复制
(defvar *p* (cvodecreate 1 2))

(PS. )不要担心传递给CVODECREATE的数字,它们只是告诉要使用哪些方法,仍然需要定义常量以提高其可读性)

所以*P*就像

代码语言:javascript
复制
#.(SB-SYS:INT-SAP #X7FFFE0007060)

如果我直接将它传递给CVODEFREE,它将以错误告终:

代码语言:javascript
复制
CL-USER> (cvodefree *p*)
; Evaluation aborted on #<SIMPLE-ERROR "bus error at #X~X" {1005EC9BD3}>.

我尝试过通过(CFFI:POINTER-ADDRESS *P*),但是它会导致类似的“总线错误.”(甚至不确定此函数是否返回我所需的内容)。我也尝试过做(CFFI:MAKE-POINTER (CFFI:POINTER-ADDRESS *P*)),但还是没有成功。

这个问题建议采用这种方法:

代码语言:javascript
复制
(cffi:with-foreign-object (p :pointer)
           (setf (cffi:mem-ref p :pointer) (cvodecreate 1 2))
           (cvodefree p))

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-26 15:07:56

是的,您的方法看起来是正确的,这里有一个小测试来展示可以直接从repl运行的概念。

代码语言:javascript
复制
(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)))

附注:我相信你现在已经知道了,很抱歉花了这么长时间才得到答案。希望这能帮助到其他人

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35841771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档