I don't understand: in
(c-define (helper-func x) (int) int "helper_func" "" (*f* x))
(define gsl-func (c-lambda (int) int "gsl_func"))
and helper_func is called by the gsl_func routine, *f* can be any Scheme closure. Then why can't the C interface accept
(define gsl-func2 (c-lambda ( (function (int) int) int) int "gsl_func"))
and generate the correct helper-func with *f* replaced by whatever function is passed to gsl-func2?
The user is free to do that in his/her code (that is what the code at the above link does). So I assume you mean "why doesn't the C interface do this automatically for the user?".
Here are a few problems that come to mind:
- This approach is not thread-safe. If two threads concurrently call
gsl-func2 with different closures, then they will clobber the value of *f* that the other thread is using.
- Even if threads are not used, imagine the case where the C code is
receiving the function and storing it away for later use in a table (for example the function is a callback attached to a particular event, say the mouse is moved, or a key is typed on the keyboard, etc). With your approach there is a single *f* which is shared by all the callbacks you install. Which means that they are not independent. In fact, whichever callback is called, the most recently installed callback will be called (because that is what *f* will contain).
In other words, the fundamental problem here is that all closures must be independent, so they cannot share state. That's why the decision to use this approach must be in the hands of the user. The system can't do this automatically.
The two solutions I explained previously solve the sharing problem, with different caveats.
Marc
Sorry, I didn't express myself clearly. What can I do: I am just a physicist...
Given
(define gsl-func2 (c-lambda ( (function (int) int) int) int "gsl_func"))
the first argument of gsl-func2 is a function f defined on the Scheme side.
The C interface now produces a C function helper_func that is passed to gsl_func: this helper_func does nothing else that calling the Scheme function f on the parameter, just in the same way *f* was used.
What I want to say in my broken way is: if it works with the global *f*, which is not yet defined, why can't it work with f? Or in other words, the Scheme f with signature (funtion (int) int) is magically converted to the C function supplied gsl_func and this C function returns f(x).
I think I have repeated the same concept a few times already :-)
michele