In some cases you have to pass a function pointer to a C function,
i.e., the library wants to call back to your application (and the
pointed-to function is called a callback function). You can pass the
address of an existing C function (that you get with lib-sym,
see Low-Level C Interface Words), but if there is no appropriate C
function, you probably want to define the function as a Forth word.
Then you need to generate a callback as described below:
Callbacks use a staged approach: First you define a callback instantiator for a certain stack effect; then you use the instantiator to produce a C function pointer from an xt (the prototype of the C function is derived from the Forth stack effect); and finally you can use the resulting C function pointer in a context that needs it.
You can generate a callback instantiator with:
Define a callback instantiator with the given signature. The
callback instantiator forth-name ( xt -- addr ) takes
an xt, and returns the address of the C function
handling that callback.
Define a callback instantiator with the given signature. The
callback instantiator forth-name ( xt -- addr ) takes
an xt, and returns the address of the C function
handling that callback. This callback is safe when called from
another thread
Each instantiator can be called callback# times, and thus can
generate that number of callbacks, with the relevant value of
callback# being the one at the time when the instantiator is
defined. I.e., you can determine that number for an instantiator by
changing the value callback# before defining the instantiator.
In other words, you need to follow a static allocation discipline for
the callbacks.
N is the number of instantiations that the next callback
instantiator can create. This number can be changed with to
callback#, and affects the callback instantiators defined after
this change.
Here is an example of a callback use with all stages:
c-library callback-test \c typedef void (*rr2v)(double,double); \c void testrr2v(rr2v f) {f(0.5,1.5);} /* function that calls a callback function f */ c-function testrr2v testrr2v a -- void c-callback rr2v-callback r r -- void \ define callback instantiator end-c-library : printrr fswap f. f. ; ' printrr rr2v-callback constant printrr-c \ generate a callback instance printrr-c testrr2v \ use the callback function pointer by passing it to testrr2v