I'm not sure this will help but, here goes...
The representation of a "function" is different for Gambit an C. In C, a function "value" is normally represented as the address of the machine code that implements this function. The C compiler generates the "call" machine instruction to call functions represented this way. On the Gambit side, a function value is represented as the address of the "closure object" which contains the environment of the closure and the code pointer. You can't use the "call" machine instruction to call such functions. Even in a Scheme system where closures are represented as a piece of code (this is possible, in fact the first versions of Gambit used this representation) you also have the problem that the parameter passing protocol may be different in C and Scheme, and it probably has to be to support "rest parameters".
So... when a Scheme function is passed to the C world, as a C function, there is a real conversion that must occur because the underlying representations and parameter passing protocol are different in the two worlds.
Does that clarify things?
Marc
It was already clear enough in your previous reply, thanks for the patience.
So the bottom line is that
(c-define (callback-wrapper x) (int) int "callback_wrapper" "" (f x))
won't work with
(letrec ((f (lambda (x) (* 4 x)))) (callback-wrapper 4))
but it will in the top level only with
(define (f p) (* 3 p)) (callback-wrapper 4) ; -> 12
michele