我正在使用 CFFI 与使用 GLib 的库进行交互。 g_list_free_full()
GLib 中的函数具有签名:
void
g_list_free_full (GList *list,
GDestroyNotify free_func);
我需要从 Lisp 中调用这个函数,因为我正在处理一些需要创建 GList
对象的函数,所以之后我还需要释放它们。在 C 中,我会这样做(另见 this answer ):
g_list_free_full(res, g_free);
到目前为止,我的 Lisp 绑定(bind)看起来像这样:
(asdf:load-system :cffi)
(defpackage :test-glib-bindings
(:use :common-lisp :cffi))
(in-package :test-glib-bindings)
(define-foreign-library libglib
(:unix (:or "libglib-2.0.so.0" "libglib-2.0.so")))
(use-foreign-library libglib)
(defctype gint :int)
(defctype gboolean :boolean)
(defctype gpointer :pointer)
(defcfun "g_free" :void
(mem gpointer))
(defcfun "g_list_free_full" :void
(lst gpointer)
(fun :pointer))
但我不确定我的 defcfun
签名是否适用于 g_list_free_full()
,我也不确定如何从 Lisp 中正确调用它。我天真的猜测是写:
(g-list-free-full my-glist (get-callback 'g-free))
但很难判断这是不是做事的正确方式(或最佳方式)。我也不是经验丰富的 C 程序员,我不知道这在技术上是否可行,但将来会导致其他问题。
最佳答案
我不确定 get-callback
是否为未使用 defcallback
声明的函数定义。这未经测试,但您可能只需要将库中的 "g_free"
符号解析为它的指针,并将该值作为参数传递。
您可以调用fs-pointer-or-lose
或foreign-symbol-ptr
来获取指向原生g_free
函数的指针;而不是调用 (get-callback 'g-free)
,你写:
(fs-pointer-or-loose "g_free")
或者,以返回 Lisp 为代价,您可以使用 defcallback
和 callback
。
为此,您需要定义一个 Lisp free
函数作为回调,并让它调用 native 函数。
(defcfun (g-free "g_free") :void (mem gpointer))
(defcallback free :void ((mem gpointer))
(g-free mem))
然后您将使用 callback
将指针传递给回调。
(g-list-free-full my-glist (callback free))
关于common-lisp - 如何将 DEFCFUN 与指向外部 C 函数的指针一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65031313/