Hi Jim, I really appreciate you looking over this!
However, I think that it may be more practical to return locatives because they are interchangeable with c-pointers. This makes them easier to pass around with other parts of the foreign-code. If we remove (locative ...) and use scheme-pointer, nested struct getters and struct return-types in scheme would return blobs instead of locatives. Let's check out this (untested) example of what I think would be typical usage: (bind " struct point { float x, y; }; struct circle { struct point origin; float radius; }; float distance(struct point, struct point);") (define c1 (make-circle (make-point 10 10) 0.5)) (define c2 (make-circle (make-point 1 1) 0.2)) ;; circle-origin is a nested-struct getter. ;; if it returns blobs, we must do: (distance (make-locative (circle-origin c1)) (make-locative (circle-origin c2))) ;; if it returns locative: (distance (circle-origin c1) (circle-origin c2)) I was not aware of the performance penalty introduced by (locative <blob>). Would it be beneficial to return the locative of the blob as a last step, and use scheme-pointer in the intermediate, destination-operand, step? Thank you, K. On Mon, Jun 25, 2012 at 10:18 PM, Jim Ursetto <zbignie...@gmail.com> wrote: > Tip: if you use scheme-pointer instead of c-pointer, you can omit the > locative). E.g. (make-blob size) instead of (location (make-blob size)). > This will be faster. > > On Jun 25, 2012, at 5:27 PM, Kristian Lein-Mathisen wrote: > > > Hi guys! > > It's me again, still going on about struct-by-value in > chicken-bind<http://wiki.call-cc.org/eggref/4/bind>. > This time I think I may have code<https://github.com/kristianlm/chicken-bind> > worthy > of entering the official repo. The patches add three new features: > > 1. Struct-by-value in arguments > 2. Struct-by-value return types > 3. Nested structs (practically same as 2) > > Functions on the Scheme-side interface all functions using pointers or > locatives, regardless of their original signature. > > You can have a look at my 10 commits that make up the patch on > github<https://github.com/kristianlm/chicken-bind/commits/>. I > tried to be descriptive in my commit messages. Please let me know of your > thoughts and concerns. If nothing pops up, I'll pass it on Felix > (chicken-bind maintainer) for review. > > *Motivation* > While most C libraries pass structs by reference, both physics engines > I've come across, Chipmunk and Box2D, pass small structs like 2d-vectors > around by value everywhere. This patch made my life easier. > > *Code samples* > Let's walk through the new foreign-lambda snippets that it generates. I > use the point struct in my examples, pretend it's some 2d/3d vector of > floats. First, let's look at passing a struct by reference: > > *1. Struct arguments* > [klm@kth chicken-bind]$ echo "float length(struct point*)" | chicken-bind > - -o - > (begin > (begin > (define length > (foreign-lambda float "length" (c-pointer (struct "point")))))) > * > * > Nothing's changed there, my patch will kick in when you pass structs by > value. The patch checks if any arguments are non-pointer struct arguments, > and if there are any, it wraps the call in a foreign-lambda* with all > struct-by-val arguments to c-pointer variant which are dereferenced in C: > > [klm@kth chicken-bind]$ echo "float length(struct point)" | chicken-bind > - -o - > (begin > (begin > (define length > (foreign-lambda* > float > (((c-pointer (struct "point")) a0)) > "C_return(length(*a0));")))) > > *2. Struct return-types* > Struct return-types are a little trickier and are split into two > functions. One will call the original function, storing the result in a > additional destination operand. The other will allocate memory to use as > this destination and calls the first: > > [klm@kth chicken-bind]$ echo "struct point intersection(struct line*, > struct line)" | chicken-bind - -o - > (begin > (begin > (begin > (define intersection/overwrite! > (foreign-lambda* > void > (((c-pointer (struct "point")) dest) > ((c-pointer (struct "line")) a0) > ((c-pointer (struct "line")) a1)) > "*dest=(intersection(a0,*a1));")) > (define (intersection a0 a1) > (let ((dest (location > (make-blob (foreign-value "sizeof(struct point)" > int))))) > (intersection/overwrite! dest a0 a1) > dest))))) > > As shown above, you can mix and match struct value-passing and > pointer-passing in the arguments. > > *3. Nested structs* > Nested structs face the same problem as struct return-types, but > unfortunately I haven't looked into uniting the codebase. However, it > follows the same destination-method as above: > > [klm@kth chicken-bind]$ echo "struct circle { struct point origin; float > radius ; }" | chicken-bind - -o - > (begin > (define circle-origin > (lambda (s) > (let ((blob (location > (make-blob (foreign-value "sizeof(struct point)" > int)))) > (copy-struct! > (foreign-lambda* > void > (((c-pointer (struct "point")) _dest) > ((c-pointer (struct "circle")) s)) > "*_dest = s->origin;"))) > (copy-struct! blob s) > blob))) > (define circle-radius > (foreign-lambda* > float > (((c-pointer (struct "circle")) s)) > "return(s->radius);")) > (define make-circle > (foreign-lambda* > (c-pointer (struct "circle")) > (((c-pointer (struct "point")) origin) (float radius)) > "struct circle *tmp_ = (struct circle *)C_malloc(sizeof(struct > circle));\ntmp_->origin = *origin;\n\ntmp_->radius = > radius;\n\nC_return(tmp_);"))) > > > *Caveats* > Struct-by-value return types and nested-struct getters return locatives. > This is nice because it will be like any other scheme-object and doesn't > need to be explicitly freed. Be careful though, locatives will be moved > around by the GC and thus pointers to it are not permanent. > > A also added a small > test-suite<https://github.com/kristianlm/chicken-bind/blob/master/tests/struct-passing-tests.scm>for > these features. > > Cheers fellow Chickeners, > - Kris > > _______________________________________________ > Chicken-users mailing list > Chicken-users@nongnu.org > https://lists.nongnu.org/mailman/listinfo/chicken-users > > >
_______________________________________________ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users