[gambit-list] cast scheme procedure to c function

Marc Feeley feeley at iro.umontreal.ca
Tue Nov 22 21:00:50 EST 2011


On 2011-11-22, at 7:52 PM, Álvaro Castro-Castilla wrote:

> Hi!
> 
> I'm trying to make a procedure that takes one argument (another procedure) and converts it to a C function, assigning it to a function pointer in C. Then I want to call that function from that pointer in C.
> I'm aware that the typical way to do this is with c-declare in a static way, but I need to be able to achieve the same without using c-declare.
> 
> My current attempt:
> 
> (define (uno) 1)
> (define bind (c-lambda (scheme-object) void "simple_callable = ___CAST(void (*)(),___arg1);"))
> (bind uno)
> 
> 
> ...then the C part, same file:
> 
> // before
> void (*simple_callable)(void);
> 
> // after (bind uno) is executed
> (*simple_callable)();
> 
> 
> 
> I guess that I'm doing either the input type or the cast (or both) wrong. Probably I'm assuming to much simply casting a "scheme-object" to a void(*)().

Indeed this is way too simplistic a view.  C has no knowledge about the representation of functions in Scheme, so the cast to a C function pointer will not do what you want.  It will simply use the data address of a Scheme function descriptor as the code address of the C function.  Not good.

> Is this what I'm trying to do even possible?

If you are willing to use non-portable C code, then I think an interface to the closure API of libffi will do the trick (even though libffi is very portable, it does not work on some platforms that have perfectly conformant C compilers, so YMMV).  In essence it is non-portable because it generates machine code at run-time and some platforms/OSes don't allow this.

If you limit yourself to portable C code (the philosophy adopted in the design of Gambit) then you can't solve that problem in a general way.  You could use the solution I explained here:

https://mercure.iro.umontreal.ca/pipermail/gambit-list/2009-January/002939.html

But that will put a (small) upper limit on the number of Scheme functions you can pass to C.

Marc





More information about the Gambit-list mailing list