help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-smalltalk] birth of a new feature: Smalltalk callbacks


From: Paolo Bonzini
Subject: [Help-smalltalk] birth of a new feature: Smalltalk callbacks
Date: Wed, 21 May 2008 16:00:13 +0200
User-agent: Thunderbird 2.0.0.14 (Macintosh/20080421)

I added the feature that Udo described, it was a good stimulus to cleanup CFunctionDescriptor handling sensibly (of course there are good reasons why Steve Byrne originally wrote them that way -- simplicity mainly; with all the features that entered GNU Smalltalk over the years, the simplest implementation is now a different one).

I'm not posting patches, I'm just describing them. You can read the patches at http://git.sv.gnu.org/gitweb/?p=smalltalk.git on savannah.

The first commit, 12fa4b57095d4b is a completion of a feature I began last April, i.e. allowing creation of CFunctionDescriptors that host a pointer to an arbitrary C function. This didn't work because they actually pointed to a C struct containing the libffi data. I'm now using a hash table to associate OOPs to libffi data. This is not yet perfect because OOPs can be reused, but I'll fix it soonish by recreating the map upon GC.

The second, 3e98b86e3b, makes CFunctionDescriptor a subclass of CObject. This fixes in a better way the impossibility to subclass CFunctionDescriptor.

The third, 81ef7546, does what I was thinking loudly about in my mail from yesterday, i.e. move the creation of CFunctionDescriptors entirely to Smalltalk code. This adds a whole lot of flexibility, so that in the next commit, 6c6e7e2ed, I create a separate class CCallable for arbitrary function pointers. Since CFunctionDescriptors have all the functionality for rebinding the symbols on image load, it makes sense to have an abstract class.

The intermezzo in 6f253188 just adds a way to call blocks using the callin functions, without manually specifying selectors like #value:value:value:value:value:...

Finally, closures are added in ffb3ff47. It's just a SMOP, since the functions for mapping C types to Smalltalk and vice versa is already there. I'll copy after my signature the relevant section of the manual. Improvements are very welcome!

Paolo


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 @code{VMProxy} functions for Smalltalk callin are not enough.

@gst{} provides a more dynamic way to convert Smalltalk blocks into
C function pointers through the @code{CCallbackDescriptor} class.
This class has a constructor method that is similar to the
@code{cCall:} annotation used for callouts.  The method is
called @code{for:returning:withArgs:} and its parameters are:

@itemize @bullet
@item a block, whose number of arguments is variable
@item a symbol representing the return type
@item an array representing the type of the arguments.
@end itemize

The array passed as the third parameter represents values that
are passed @emph{from C to Smalltalk} and, as such, should be
filled with the same rules that are used by the @emph{return
  type} of a C callout.  In particular, if the C callback
accepts an @code{int *} it is possible (and indeed useful)
to specify the type of the argument as @address@hidden@}},
so that the block will receive a @code{CInt} object.

Here is an example of creating a callback which is passed to
@address@hidden GLUT bindings use a different
  scheme for setting up callbacks.}.  The desired
signature in C is @code{void (*) (int, int)}.
@example
| glut |
@address@hidden
glut glutReshapeFunc: (CCallbackDescriptor
    for: [ :x :y | self reshape: x@@y ]
    returning: #void
    withArgs: #(#int #int))
@end example

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 @code{link}
message before it is passed to any C function.  Sending the @code{link}
message to an already valid callback is harmless and cheap.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]