[plt-scheme] Binding C-Structs Containing Fixed-Size Arrays with the FFI
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!