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

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

On Jan 26, Henk Boom wrote:
> 2009/1/26 Eli Barzilay <eli at barzilay.org>:
> > Ah, I missed that.  No, this is forbidden: the GC won't know about
> > it, so it will move the block leaving you with most likely invalid
> > pointer.  (And from the rest of your message it looks like that's
> > what happened.)
> >
> > This is the reason why pointers have offsets, that's probably the
> > way to solve your problem.
> I see. So instead of using make-ctype to do the conversion, I want
> to use a custom accessor for the field, which takes a pointer to the
> struct and offsets it to point to the array instead. Am I right so
> far?

Yes, I think so.

> I have looked through the pointer functions documentation,
> specifically at the pointer offset functions. I've come up with the
> following:
> (define _dReal _float)
> (define _dVector3 _cvector)
> (define _dVector3-direct
>   (make-cstruct-type (list _dReal _dReal _dReal _dReal)))
> (define-cstruct _foo
>   ((private-i _dVector3-direct)
>    (private-j _dVector3-direct)))
> (define (foo-i f) (make-cvector* f _dReal 4))
> (define (foo-f f) (make-cvector* (ptr-add f ???) _dReal 4)
> The problem is in the definition of foo-f. I can't see any way of
> finding the field's offset, since there seems not to be a pointer
> difference function. Am I on the right track? Where should I look
> next?

It is possible to do pointer subtraction, using code that treats them
like integers -- but that's pretty horrible IMO.  Anyway, providing
such a function in general is not going to be a good idea because
there wouldn't be a way to know that you're getting sensible results.
In the above code, such a subtraction will make sense, but what if you
give it two pointes to two objects that are not related?  -- In this
case the result will be some random number that depends on where they
happen to be in memory.

I think that a better solution will be to use the offsets that are
computed at the Scheme level.  I don't think that they're available
now, so perhaps some extension to the API will be best here.  It might
also be easiest to just use the primitive functionality: use
`make-cstruct-type' directly with a list of offsets.

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

Posted on the users mailing list.