Here is a simple example of using callbacks.
(use-package :alien) (use-package :c-call) (def-callback foo (int (arg1 int) (arg2 int)) (format t "~&foo: ~S, ~S~%" arg1 arg2) (+ arg1 arg2)) (defun test-foo () (callback-funcall foo 555 444444))
In this example, the callback function foo is defined which
takes two C int parameters and returns a int. As this
shows, we can use arbitrary Lisp inside the function.
The function test-foo shows how we can call this callback
function from Lisp. The macro callback extracts the necessary
information for the callback function foo which can be
converted into a pointer which we can call via alien-funcall.
The following code is a more complete example where a foreign routine calls our Lisp routine.
(use-package :alien)
(use-package :c-call)
(def-alien-routine qsort void
(base (* t))
(nmemb int)
(size int)
(compar (* (function int (* t) (* t)))))
(def-callback my< (int (arg1 (* double))
(arg2 (* double)))
(let ((a1 (deref arg1))
(a2 (deref arg2)))
(cond ((= a1 a2) 0)
((< a1 a2) -1)
(t +1))))
(defun test-qsort ()
(let ((a (make-array 10 :element-type 'double-float
:initial-contents '(0.1d0 0.5d0 0.2d0 1.2d0 1.5d0
2.5d0 0.0d0 0.1d0 0.2d0 0.3d0))))
(print a)
(qsort (sys:vector-sap a)
(length a)
(alien-size double :bytes)
(alien:callback my<))
(print a)))
We define the alien routine, qsort, and a callback, my<,
to determine whether two double’s are less than, greater than
or equal to each other.
The test function test-qsort shows how we can call the alien
sort routine with our Lisp comparison routine to produce a sorted
array.