在系统区域内存中存储指向lisp对象的指针

时间:2014-02-09 22:01:56

标签: common-lisp sbcl

我想使用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在指向对象移动时更新指针。

1 个答案:

答案 0 :(得分:0)

虽然我不相信(虽然我急于纠正)SBCL允许人们长时间“固定”对象的指针地址,垃圾收集器也不容易扩展到更新“外部副本“指向对象的指针,你可以获取一个指向Lisp回调函数的持久指针;即使用funcall C程序可以defcallback实际上是Lisp函数的指针。

一个(未经测试的)理论可能是以这样的方式包装你的C语言:

  • C函数使用NULL指针插槽分配c_struct
  • 您为C程序提供(defcallback …)函数指针; 我们称之为void with_locked_access ((void*) interior_function(struct c_struct *), struct c_struct *struct_to_use)
  • 当C函数想要访问此指针时,他们使用自己的函数指针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