Reputation: 13913
I am using CFFI to interact with a library that uses GLib. The g_list_free_full()
function in GLib has the signature:
void
g_list_free_full (GList *list,
GDestroyNotify free_func);
I will need to call this function from Lisp because I am working with some functions in which I need to create GList
objects, so I also need to free them afterwards. In C, I would do it like this (see also this answer):
g_list_free_full(res, g_free);
So far my Lisp bindings look like this:
(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))
But I'm not sure if my defcfun
signature is correct for g_list_free_full()
, and I'm not sure how to call it correctly from Lisp. My naive guess is to write:
(g-list-free-full my-glist (get-callback 'g-free))
but it's hard to tell if this is the right way (or best way) to do things. I'm also not an experienced C programmer, and I don't know if this will technically work but cause some kind of other problem in the future.
Upvotes: 3
Views: 243
Reputation: 38967
I am not sure if get-callback
is defined for functions not declared with defcallback
. This is not tested, but you probably only need to resolve the "g_free"
symbol in the library to its pointer, and pass this value as an argument.
You can call fs-pointer-or-lose
or foreign-symbol-ptr
to get the pointer to the native g_free
function; instead of calling (get-callback 'g-free)
, you write:
(fs-pointer-or-loose "g_free")
Alternatively, at the cost of doing a trip back to Lisp, you can use defcallback
and callback
.
For that, you need define a Lisp free
function as a callback, and have it call the native function.
(defcfun (g-free "g_free") :void (mem gpointer))
(defcallback free :void ((mem gpointer))
(g-free mem))
Then you would pass the pointer to the callback with callback
.
(g-list-free-full my-glist (callback free))
Upvotes: 1