[plt-scheme] Binding C-Structs Containing Fixed-Size Arrays with the FFI

From: Eli Barzilay (eli at barzilay.org)
Date: Tue Jan 27 10:32:26 EST 2009

On Jan 27, Jakub Piotr C?apa wrote:
> On 1/26/09 9:36 PM, Eli Barzilay wrote:
> > On Jan 26, Jakub Piotr C?apa wrote:
> >> You may want to check these threads:
> >>
> >> http://thread.gmane.org/gmane.lisp.scheme.plt/12987
> >> http://thread.gmane.org/gmane.lisp.scheme.plt/28412/focus=28509
> >> http://list.cs.brown.edu/pipermail/plt-scheme/2007-March/016671.html
> >
> > The quick version is: libffi doesn't have a way to do so.  You
> > need to either fake it with structs like Matthew showed, or you
> > can do it more manually: malloc a piece of memory and `ptr-ref'
> > parts of it directly.  But that won't work inside a struct -- I
> > don't know of any API in libffi to create a type with a given
> > size/alignment.
> 
> This is true but:
> 1. _path-type [1] worked quite well in my case.
> 2. The problem is mostly with homogeneus arrays inside structs which
>     AFAIK always have the same alignment as their basic element type.
>     (it may not be true with SIMD but in those cases even plain C does
>     not give you correct aligments without manual tweaking)

Right.  This is why I keep hoping that someone would point me at some
obvious thing that I missed -- it seems like it would be easy to
implement it (but requires someone who knows about the librffi
implementation).


> So even if the solution is not elegant (I don't like it either) it
> works in all practical situations and saves the day. As far as I
> understand you also do not know of any better means to do it.
> 
> Considering the above I suggested to mention this solution (and
> obviously any of it's deficiencies we know of) in the FFI manual.
> 
> [1]: http://thread.gmane.org/gmane.lisp.scheme.plt/28412/focus=28509

Yes, that one is similar to Matthew's suggestion.


> P.S. Couldn't we just ignore libffi struct handling and just do it
> in Scheme like Scheme->C did? (they compiled a test C program which
> computed and printed out the needed aligments and sizes) libffi
> would only be used for calls and callbacks (this seems to be done
> very well). I understand this is much work (and may not be worth the
> trouble) but are there any formal shortcomings I don't see?

If you look in the Scheme source for the foreign interface, you'll see
that it actually does this for structs.  The thing is that libffi
provides a way to define a struct, but no way to access its parts.
(Again, it would be nice if the libffi api had at least functions to
know what the offsets are, but since I didn't find anything like that
I implemented that computation in Scheme.)

But to be able to define a libffi type with an in-line array, I need
to give something to libffi so it can construct its type.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!


Posted on the users mailing list.