[plt-scheme] FFI questions:

From: Jay Kominek (kominek at gmail.com)
Date: Wed Nov 12 20:15:05 EST 2008

On Wed, Nov 12, 2008 at 3:18 PM, Ernie Smith <esmith at acanac.net> wrote:
> I feel as though I'm missing key pieces of information
> which would permit me finally to grasp the FFI documentation.
> In an effort to discover the missing link I've come up with a
> few questions, I'd be grateful for answers.  More importantly,
> if in reading these questions it dawns on someone that I am
> missing a concept please feel free to slap me into consciousness
> with the necessary point.
> 1- Given that you create a type using this:
>  (make-ctype ctype ...)
>  How do you create an initialized instance of that type?

I think the piece of information you're missing is: you don't have to
(and I don't think you can).

The C types are conversion routines that get invoked when data has to
move from Scheme to C, or vice versa. The ones you provide to
make-ctype just go from one sort of Scheme value to another. The
built-in ones, _int, _float, etc, are (as near as I can tell),
magical, and do the actual conversion to stuff that'll make it to the
C functions.

> (require scheme/foreign)
> (unsafe!)
> (get-ffi-obj "roundf" #f (_fun _float -> _float))
> (define roundf (get-ffi-obj "roundf" #f (_fun _float -> _float)))
> (roundf 5.5)
> (roundf 3.141592)
> (number? (roundf 3.141592))
> (define _silly_float
    (make-ctype _float
      (lambda (schemev) (if schemev schemev 0.0))
      (lambda (cv) (if (= cv 0.0) #f cv))))
> (define sillyroundf (get-ffi-obj "roundf" #f (_fun _silly_float -> _silly_float)))
> (sillyroundf 3.1)
> (sillyroundf #f)
> (sillyroundf 0.1)

So the idea behind _float, for instance, isn't to create a value of
some type which doesn't satisfy number? or inexact?, but rather, to
tell the FFI layer what conversion to perform on Scheme values so that
they're in a form that C expects.

I hope I managed to shed some light on things for you.

Jay Kominek

Posted on the users mailing list.