我想使用Common Lisp为C程序处理一些东西。但由于某些原因,我需要使用SBCL。
我想知道如何在由C函数分配的系统区域内存中正确存储指向lisp对象的指针。例如,
struct c_struct {
...
lispobj *obj;
...
};
使用sb-kernel:get-lisp-obj-address
,我可以获得指向lisp对象的指针。但它没有把它存储在外国记忆中。主要问题是GC移动对象。 sb-sys:with-pinned-object
仅在身体范围内钉住物体,并且长时间固定物体显然是个坏主意。所以我需要一些方法告诉GC在指向对象移动时更新指针。
答案 0 :(得分:0)
虽然我不相信(虽然我急于纠正)SBCL允许人们长时间“固定”对象的指针地址,垃圾收集器也不容易扩展到更新“外部副本“指向对象的指针,你可以获取一个指向Lisp回调函数的持久指针;即使用funcall
C程序可以defcallback
实际上是Lisp函数的指针。
一个(未经测试的)理论可能是以这样的方式包装你的C语言:
c_struct
(defcallback …)
函数指针;
我们称之为void with_locked_access ((void*) interior_function(struct c_struct *), struct c_struct *struct_to_use)
interior_function
和指向感兴趣的interior_function
的指针调用c_struct
interior_function
实际上是(defcallback call-c-with-pinned-object…)
;反过来,它调用sb-sys:with-pinned-object
并获取对象的系统区域指针,并在调用c_struct
之前将其存储到interior_function
中,并将(现在填充的)结构作为其参数。 interior_function
做它想要固定的Lisp对象的任何东西;它会返回,call-c-with-pinned-object
会关闭with-pinned-object
表单并自行返回。当然,这完全取决于你想在C代码中做什么,以及它是否会与Lisp代码并行运行,这可能会受到钉扎和c&amp; c的负面影响。< / p>
或者,在特殊(但常见)情况下,所讨论的对象恰好是字节向量(例如,某种缓冲区),您可以利用cffi-sys:make-shareable-byte-vector
和{{ 1}},qv