[cffi-devel] stdcall callbacks on ClozureCL/win32

Gary Byers gb at clozure.com
Thu Jun 4 09:59:14 UTC 2009


Hi.

In the thread starting in:

<http://common-lisp.net/pipermail/cl-opengl-devel/2009-June/000585.html>

someone described problems running some CL-OPENGL GLUT examples in
Clozure CL on Win32.

I'm not sure if this is the only problem, but it seems that the most
functions defined in the FreeGLUT library use the 'stdcall' calling
convention (a "Pascal"-like calling sequence where the callee is
responsible for discarding args from the stack, sometimes used on
Win32 for no obvious reason besides backward compatibility ...) and it
seems reasonable to assume that it expects user-defined functions that
it calls to follow this convention as well.

Because of implementation arcana, CCL doesn't really care whether
a foreign function that it calls follows 'stdcall' or 'cdecl' conventions.
The caller of a callback function (defined via CCL:DEFCALLBACK or the
CFFI equivalent) may very well care, and the callback machinery has to
be told which conventions to follow.

A callback function that accepts two 'int' arguments and returns their
sum as an 'int' would be defined in CCL as:

(ccl:defcallback add-two-ints (:int x :int y :int)
   ;; The arglist declares X and Y to be C ints and that the function returns
   ;; a value of type 'int'.
   (+ x y))


That makes the value of ADD-TWO-INTS a foreign pointer to
foreign-callable code that ultimately just adds a couple of signed
32-bit integers.  By default, the glue code that handles the
transition from C to lisp and back again when this function is called
from foreign code assumes that pretty standard C calling conventions
are being followed (all args are passed on the stack and left there when
the callee returns, with a possible exception involving the invisible
argument used to effect structure return.)

If we wanted to define a callback that followed 'stdcall' conventions,
we can do so by prepending the keyword :DISCARD-STACK-ARGS to the callback's
argument list:

(ccl:defcallback stdcall-add-two-ints (:discard-stack-args :int x :int y :int)
   ;; note that there's just a :DISCARD-STACK-ARGS keyword at the front of the
   ;; arglist, not a key/value pair
   (+ x y))

I'm fairly sure that the runtime effects of :DISCARD-STACK-ARGS will only
occur on Win32 (e.g., that it's a no-op on other platforms).

I'd assume that anyone who's:

   a) more familiar with CFFI than I am and
   b) less lazy than I am

can add support for stdcall-style callbacks to CFFI's OpenMCL/CCL-backend code,
and doing so might help to get things like CL-OPENGL working on CCL/win32.

If anyone has any questions abou the CCL side of this, I'd be glad to try to
answer them.

It looks like CFFI is generally familiar with this cdecl/stdcall stuff and
has the infrastructure in place to do the right thing, but the CCL backend
just doesn't implement it.




More information about the cffi-devel mailing list