[Openmcl-devel] A (stupid?) question

Gary Byers gb at clozure.com
Thu Jul 31 22:30:12 UTC 2003

On Thu, 31 Jul 2003, Jubal wrote:

> I was looking at the documentation for the OpenMCL foreign function
> interface and was intrigued by the defcallback macro. I understand (I
> think) what is does, but I am confused as to how one takes advantage of
> this functionality. Specifially, how does one write C code that takes
> advantage of the callback defined by defcallback. Say, (for a really
> silly example) I wanted to do the following:
> (defcallback exchange (:single-float dollars :single-float rate
> :single-float)
> 	(* dollars rate))
> How would I then write a C program to call that function?

One example of a (fairly) well-known C function that takes a function
as an argument is qsort, whose prototype is something like:

     qsort(void *base, size_t nmemb, size_t size,
             int (*compar)(const void *, const void *));

As is clearly obvious to anyone with the intuitive ability to parse
C function prototypes ... uh, I'd sort of guess that qsort's 4th argument
is supposed to be a function that takes two pointers as arguments and
returns an int.

(defcallback sort-char-pointers-for-qsort (:address pointer-a
                                           :address pointer-b

  ;; If we read the qsort man page, we'll eventually discover that
  ;; we're supposed to return a negative value if the thing pointer-a
  ;; points to is less than the thing pointer-b points to, 0 if they're
  ;; equal, and a positive value otherwise.

  (let* ((thing-a (pref pointer-a :unsigned-byte))
         (thing-b (pref pointer-b :unsigned-byte)))
     (if (< thing-a thing-b)
       (if (= thing-a thing-b)

(defun sort-string-the-hard-way (string)
  (with-cstrs ((cstring string))
    (#_qsort cstring (length string) 1 sort-char-pointers-for-qsort)
    (%get-cstring cstring)))

That's a case where we pass a C-callable function pointer to a function
that we're calling.  A given C library might provide an interface where
function pointers are to be stored in global memory locations, or passed
as arguments to initialization functions, or follow some other convention.
A function pointer defined by DEFCALLBACK obviously does need to be passed
to the foreign code that's going to call it -somehow-; the mechanism that's
used is generally defined by the caller (the C library or function that
needs/uses the function pointer.)

> Or am I completely missing the point?

Not really.  qsort's the only example of a callback function that I can
think of in the standard C library.  Some other C libraries (windowing
toolkits, for example) make heavy uses of the mechanism.  It generally
doesn't make sense to talk about passing callback functions around unless
there's some convention for their use;  DEFCALLBACK provides a way to
define those functions when they're required, but doesn't define the
conventions by which they're used.

> --Paul
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/cgi-bin/mailman/listinfo/openmcl-devel

Openmcl-devel mailing list
Openmcl-devel at clozure.com

More information about the Openmcl-devel mailing list