[plt-scheme] Manipulating Scheme vectors with FFI

From: Will Farr (farr at mit.edu)
Date: Tue Oct 28 14:51:46 EDT 2008


You should look at the SRFI-4 vectors from Section 6.3 of the FFI: PLT
Scheme Foreign Interface.  In particular, the type you want is
_f32vector, with the associated (make-f32vector ...) and
(f32vector-set! ...) functions.  This data type is distinct from
ordinary Scheme vectors because it can *only* store 32-bit floats.  In
exchange for this loss of flexibility, it stores the floats unboxed in
the array, just as in block of memory pointed to by a C "float *".  It
is passed to foreign functions by address (that is, the address of the
memory block storing the floats); a foreign function cannot return a
f32vector (and, as far as I can see from the mzlib/foregin.ss sources,
there is no way to take an arbitrary pointer and make an f32vector out
of it).

Good luck!


On Tue, Oct 28, 2008 at 9:42 AM, Benjamin Seppke
<benjamin.seppke at gmail.com> wrote:
> Hi everybody!
> I'm very familiar with Scheme, but relatively new to the FFI (foreign
> function interface) of Dr/MzScheme. It seems to be more different from
> the one implemented in CommonLisp  (Allegro CL) that I thought.
> The use case is, that  I want to call vector manipulation functions
> that are written in C++ and linked via a C - dynamic library.
> At the C-side a typical signature ist:
> LIBEXPORT int function1(const float *arr1, const float *arr2,const
> int length, const  float param)
> I have two constant pointers to non-constant data. This function does
> something using the contents of array1  (of length "length") and saves
> the result to array2 (of equal length).
> So I wanted to do the following steps in Scheme:
> 1. Create both vectors (arr1, arr2)
> 2. send them to the function (via ffi)
> 3. read the contents of arr2 and the resulting int-value (0 means no
> error occured during calculation in the C function)
> And that's it on the Scheme side:
> (require scheme/foreign)
> (unsafe!)
> (define lib_c (ffi-lib "somewhere.dylib"))
> (define ggm
>    (get-ffi-obj "fun_c" lib_c (_fun (arr1 arr2 l s) ::
> (arr1 : (_vector i _float))
> (arr2 : (_vector i _float))
> (l : _int)
> (s : _float) -> _int)
>                 (lambda ()
>                   (error 'c_lib "installed foolib does not provide
> \"fun_c\""))))
> (define length 10000)
> (define arr1 (make-vector length 2.0))
> (define arr2 (make-vector length 1.0))
> (define s 10.0)
> (vector-set! arr1 5000 50.0)
> (ggm arr1 arr2 length s)
> The bindings work well, if I play with the parameters I get a failure
> returned by the ggm function (resulting in a 1 delivered by the c-
> function). However, the result is never visible to me, the second
> vector arr2 still consists of the initial values 1.0 which should not
> happen.
> I already tried to use arr2: (_vector i _float) or (_vector io
> _float)  in the scheme ffi parameter list, but this resulted in the
> following error:
>  _vector: bad syntax in: (_vector io _float)
> the same for _cvector....
> So my question is: How can I manipulate Scheme vectors inside a c-
> function and see the results of that in Scheme..?
> Thanks in advance,
> Benjamin
> _________________________________________________
>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme

Posted on the users mailing list.