scsh-users
[Top] [All Lists]

Re: Scsh (a Unix Scheme shell) FAQ

To: scsh-news@martigny.ai.mit.edu
Subject: Re: Scsh (a Unix Scheme shell) FAQ
From: serrano@divsun.unige.ch (SERRANO Manuel)
Date: 14 Oct 1997 08:25:27 GMT
Organization: University of Geneva, Switzerland
Resent-to: scsh-list@martigny.ai.mit.edu
> 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--

<Prev in Thread] Current Thread [Next in Thread>
  • Re: Scsh (a Unix Scheme shell) FAQ, SERRANO Manuel <=