common-lisp - 如何将 DEFCFUN 与指向外部 C 函数的指针一起使用?

标签 common-lisp glib cffi

我正在使用 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-loseforeign-symbol-ptr 来获取指向原生g_free 函数的指针;而不是调用 (get-callback 'g-free),你写:

(fs-pointer-or-loose "g_free")

或者,以返回 Lisp 为代价,您可以使用 defcallbackcallback。 为此,您需要定义一个 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/

相关文章:

emacs - 如何让 SLIME 从加载的其他包中自动完成符号?

Lispworks 编辑器颜色编码

c++ - Netbeans 不包括 glib.h ,即使它存在,如自动完成所示。该怎么办?

common-lisp - 如何在defsystem中设置C编译器?

clojure - 为什么 eval 是邪恶的?

macros - Lisp 宏 set-or-nconc 无法正常工作

c++ - GLIB 安装后无法编译基本 GLIB 程序

c - 为什么我的 Thrift (c_glib) 客户端失败并出现 "invalid pointer"错误?

c - 使用 CFFI 从 Common Lisp 向堆栈上的 C 函数传递和返回结构