[plt-scheme] Eli Barzilay's new FFI stuff
On Aug 7, Christopher Armstrong wrote:
> On Sat, 7 Aug 2004 16:50:18 -0400, Eli Barzilay <eli at barzilay.org> wrote:
> > Definitely not! It's not the names which are a problem -- it's the
> > fact that the ptr-ref will copy the contained substructure instance.
> > But this is only a problem that is imposed by the pointer tags, which
> > is the technical problem I mentioned in the previous email.
>
> Ok, I think I vaguely understand what you just said. :-) So, how can
> I solve or work around this problem?
Well, you can edit foreign.ss and disable all pointer tags, or wait
for me... I'll send you a message when I get to it.
> On further discussion with my colleagues, I may be incorrect about
> this. While it may be applicable to my current use case, it may not
> be a generally good idea.
>
> The problem cited was padding issues - that structs may be padded at
> the end, and the padding is platform/compiler dependant. So if your C
> code has
> typedef struct {
> super SuperStruct;
> int foo;
> } FooBar
>
> the location of 'foo' may be different based on padding at the end
> of SuperStruct, so! depending on the way that was compiled, or
> whatever, (define-cstruct foo-bar ([super _superstruct] [foo _int]))
> may or may not have the same in-memory representation. I think
> that's how it went, anyway. :-) And I have no idea how you'd solve
> this in a general way.
I've never heard of such padding, but libffi does handle alignment
issues if this is the problem. If you define
typedef struct { char a, b, c; } foo;
typedef struct { foo x; char d; } bar;
then the alignment of `foo' is 1, so `d' is always at offset 3 (if you
either do it this way, or put the fields straight into bar).
I just tried it with this:
int main(int argc, char *argv[]) {
bar b;
printf(">>> %d\n", (int)(&(b.d)) - (int)(&b));
}
and it seems to be true for sun and linux. If you know about any
additional padding, then a reference would be nice...
> Now, I think (hope) this doesn't matter in *my* case because the
> structs that I'm interfacing to actually _don't_ use the
> C-equivalent of this technique; instead, they use a CPP define
> containing all the members of the struct and say stuff like
>
> typedef struct {
> SuperStruct_HEAD // There is also an actual SuperStruct, which is
> what I'm using
> int foo;
> } FooBar;
This seems like an unnecessary hack if what I said above is correct.
So the fact that there is a library that does that makes me worried
that there might be a problem.
> [Sigh, now I'm even hearing stuff about how there could be padding
> differences even without including other structs. This is frikkin'
> depressing. I'll just try to keep doing it the way I'm doing it and
> see if I run into problems.]
Well, if it is only alignment padding, then libffi will do things
right.
> But anyway, in the case where I _do_ want to do it this way - what
> were you talking about hacking something up quick? AIUI no extra
> support is necessary in your library for me to do sub-structing in
> this way (as I'm already doing it this way without extra support,
> and with apparent success :).
If you do it this way, then the main problem you have is the
unnecessary copying of the substruct on every fireld reference. But
that will do for now, until I add support.
> Well, how else can I extract the string from that struct?
You can convert the whole struct to a byte string (which doesn't add
any overhead), then look in that string beyond the header. I'll need
to see if there is any other way to do this.
> I admit I don't understand the interaction between the GC and your
> FFI; but isn't it only the scheme-encapsulation of the pointer
> object returned from (mystring-sval-pointer mystring) that needs to
> be GC-watched, not the actual pointer itself?
But this scheme pointer object does contain a pointer, so the GC will
want to account for what that pointer points to.
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!