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

Common lisp 将指向lisp对象的指针存储在系统区域内存中,common-lisp,sbcl,Common Lisp,Sbcl,我想使用CommonLisp为C程序处理一些东西。但出于某些原因,我需要使用SBCL 我想知道如何将指向lisp对象的指针正确地存储在由C函数分配的系统区域内存中。比如说, struct c_struct { ... lispobj *obj; ... }; 使用sb kernel:get lisp obj address,我可以获得指向lisp对象的指针。但将其存储在外部存储器中毫无意义。主要问题是GC移动对象sb sys:with pinted object仅在身体

我想使用CommonLisp为C程序处理一些东西。但出于某些原因,我需要使用SBCL

我想知道如何将指向lisp对象的指针正确地存储在由C函数分配的系统区域内存中。比如说,

struct c_struct {
    ...
    lispobj *obj;
    ...
};
使用sb kernel:get lisp obj address,我可以获得指向lisp对象的指针。但将其存储在外部存储器中毫无意义。主要问题是GC移动对象
sb sys:with pinted object
仅在身体范围内固定对象,长时间固定对象显然是个坏主意。因此,我需要一些方法来告诉GC在移动指针对象时更新指针。

虽然我不相信(尽管我渴望得到纠正)SBCL允许人们在很长时间内“锁定”对象的指针地址,但垃圾收集器也不容易扩展到更新指向对象的指针的“外部副本”,您可以获得指向Lisp回调函数的持久指针;i、 e.一个C程序可以使用
defcallback
的指针,它实际上是一个Lisp函数

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

  • C函数使用空指针槽分配
    C_struct
  • 提供指向C程序的
    (defcallback…
    函数指针; 让我们称之为
    void with_locked_access((void*)internal_函数(struct c_struct*),struct c_struct*struct_to_use)
  • 当C函数想要访问此指针时,它们使用自己的函数指针
    interior\u function
    和指向感兴趣的
    C\u结构的指针调用
    interior\u function
  • 内部函数实际上是
    (defcallback call-c-with-pinted-object…)
    ;它依次调用
    sb sys:with pinted object
    ,获取对象的系统区域指针,并将其存储到
    c_struct
    中,然后调用
    interior_function
    ,将(现在填充的)结构作为其参数
  • interior\u函数
    执行它希望固定的Lisp对象的任何操作;它返回,
    call-c-with-pinted-object
    关闭
    with-pinted-object
    表单并返回自身
当然,这完全取决于您希望在C代码中执行什么操作,以及它是否将与可能受到钉住影响的Lisp代码并行运行&C&C


或者,在特殊(但常见)情况下,所讨论的对象恰好是字节向量(例如,可能是某种缓冲区),您可以利用
cffi sys:make sharedable byte vector
cffi sys:with pointer to vector data
,q.v.

对“[是吗]是否可能将指向lisp对象的指针存储在由C函数分配的系统区域内存中?“是”或“否”。如果你能展示一些做你想要的事情的代码,并指出你想做什么,特别是你想做什么,你就更有可能得到一个有用的答案。因为你使用的是SBCL,你也应该看看手册,特别是章节。你会发现很多关于如何访问外来值、如何取消引用指针等的信息。我已经编辑了我的文章。我已经看过手册了。但它并没有说要将lisp对象存储在外部内存中,但如何调用-c-with-pinted-object来知道c_struct的实例引用的是哪个对象呢?如果它是通过查找存储在c_struct中的名称获得的,那么实现将不会比只将名称保存在c_struct中更有效。使用指针的好处是可以在固定时间内找到对象。lisp对象不太可能是字节向量。如果对象可以很容易地在外部数据结构中表示,那么最好将对象直接存储在c_struct指向的外部内存中。