> Hi all,
>
> Is there any way in Bigloo to call a C function which expects a pointer
> to a function? Is there any way to do this in any Scheme?
>
> For example, say I have a C integration function:
>
> float integrate(float (*f)(float), float a, float b);
>
> which integrates a function f(x) from a to b. I want to call this
> function from C, using a Scheme procedure or lambda-expression as the
> argument:
>
> (c-integrate (lambda (x) (cos x)) 0.0 3.14)
> -- or --
> (define (foo::float x::float)
> ...)
> (c-integrate foo 0.0 1.0)
>
> Is there any way to do this?
>
> As far as I can tell in Bigloo, I can declare the function c-integrate
> to accept a pointer-to-function argument, and I can declare a type for
> pointers-to-functions, but I don't know of any way to convert a
> Scheme procedure type into a C pointer-to-function.
Up to now, there is no way to do this without a little bit of hackery. Your
mail makes me realize that I have to improve this. I will do it for the
release 1.9c.
For today, the way to write your program is the following:
1- Use cigloo to get the Bigloo representation for your C type. That is, use
something like:
> echo "float integrate(float (*f)(float), float a, float b);" | cigloo
;; Cigloo (v0.4), to be used with Bigloo (1.9).
(directives
(extern
(integrate::float (*float->float float float) "integrate")
(type float->float "float $(float)")
(type *float->float (function float (float)) "float (*$)(float)")
(type *float->float,float,float->float "float $(float
(*)(float),float,float)")
))
At this point you get your C function type: *float->float.
Now you write your Scheme function as written in your mail:
(define (foo::float x::float)
...)
Here is coming the hack:
The first think you have to do, is to export to C your Scheme foo function.
To do this you have to write an external module clause like:
(extern (export foo "c_foo"))
The only mean of this C exportation is to get a C name for your function.
Now, you are allowed to use c_foo in C, so you are allowed to write
something like:
(intergate (pragma::*float->float "c_foo") 1.0 2.0)
To summarize there is your complete code:
-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----
(module foo
(extern
(integrate::float (*float->float float float) "integrate")
(type float->float "float $(float)")
(type *float->float (function float (float)) "float (*$)(float)")
(type *float->float,float,float->float "float $(float
(*)(float),float,float)")
(export foo "c_foo"))
(export (foo::float ::float)))
(define (foo x) x)
(integrate (pragma::*float->float "c_foo") 1.0 2.0)
-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----
I agree that all this is really tricky and hacky. I will improve this as
soon as possible.
--Manuel Serrano--
|