Next: Other C functions, Previous: Smalltalk callin, Up: C and Smalltalk
The Smalltalk callin mechanism can be used effectively to construct bindings to C libraries that require callbacks into Smalltalk. However, it is a “static” mechanism, as the callback functions passed to the libraries have to be written in C and their type signatures are fixed.
If the signatures of the callbacks are not known in advance,
and the only way to define callbacks is via C function pointers (as
opposed to reflective mechanisms such as the ones in GTK+), then
the VMProxy
functions for Smalltalk callin are not enough.
GNU Smalltalk provides a more dynamic way to convert Smalltalk blocks into
C function pointers through the CCallbackDescriptor
class.
This class has a constructor method that is similar to the
cCall:
annotation used for callouts. The method is
called for:returning:withArgs:
and its parameters are:
The array passed as the third parameter represents values that
are passed from C to Smalltalk and, as such, should be
filled with the same rules that are used by the return
type of a C callout. In particular, if the C callback
accepts an int *
it is possible (and indeed useful)
to specify the type of the argument as #{CInt}
,
so that the block will receive a CInt
object.
Here is an example of creating a callback which is passed to
glutReshapeFunc
19. The desired
signature in C is void (*) (int, int)
.
| glut |
…
glut glutReshapeFunc: (CCallbackDescriptor
for: [ :x :y | self reshape: x@y ]
returning: #void
withArgs: #(#int #int))
It is important to note that this kind of callback does not survive
across an image load (this restriction may be lifted in a future version).
When the image is loaded, it has to be reset by sending it the link
message before it is passed to any C function. Sending the link
message to an already valid callback is harmless and cheap.
Next: Other C functions, Previous: Smalltalk callin, Up: C and Smalltalk