[gambit-list] Proper usage of ffi structs

Chris Mueller ruunsmail at gmail.com
Thu Aug 22 10:48:46 EDT 2013


Good point.

But gsc / gcc are reclaiming ___result_voidstar is of type
void* and has no elements x and y therefore.

Manually casting to struct point* is of course possible, but will result
in an expected segmentation fault during the execution of the script.


On 22.08.2013 08:34, Mikael wrote:
> What about you presume that ___result_voidstar is already allocated, and
> you just access/mutate it? I.e.
>
>
> (define make-point
>     (c-lambda (int int) struct-point
>       "___result_voidstar->.x = ___arg1;
> ___result_voidstar->y = ___arg2;"))
>
> ?
>
>
>
> 2013/8/22 Chris Mueller <ruunsmail at gmail.com <mailto:ruunsmail at gmail.com>>
>
>     I'm opening a new subject for the ffi struct issue to sum up the current
>     discussion:
>
>     In 19.1 "The Mapping of types between C and Scheme" of the gambit
>     documentation is mentioned:
>
>     "In the case of the struct, union and type types, the default function
>     reclaims the copy on the C heap referenced by the internal pointer (when
>     using a C++ compiler this is done using ‘delete
>     (type*)internal-pointer’, which calls the destructor of type if it is a
>     class) and returns ‘___FIX(___NO_ERR)’. In many situations the default
>     release-function will perform the appropriate cleanup for the foreign
>     type."
>
>     If i interpret this correctly, a declared struct type in a ffi provides
>     a default release function that automatically calls a destructor (used
>     with g++) and frees the corresponding memory.
>
>     Unfortanetly, i'm little lost to use it correctly and experiment
>     currently heavily to find the right way.
>
>
>     Assume a type:
>
>     (c-declare "struct point { int x; int y; };")
>     (c-define-type struct-point (struct "point"))
>
>
>     Assume a test programm that allocates a point 1_000_000_000 times.
>
>     (define (alloc-point times)
>         (let loop ((i 0))
>            (if (< i times)
>              (let ((a (make-point 0 0)))
>                (loop (+ i 1)))))))
>
>     (alloc-point 1000000000)
>
>
>     How do we implement (make-point x y) to use a ffi struct type with a
>     default release function in Gambit?
>
>     1) With a manually allocated pointer it will leak memory.
>
>     (define make-point
>         (c-lambda (int int) struct-point
>           "point* a = new Point;
>            a->x = ___arg1;
>            a->y = ___arg2;
>            ___result_voidstar = a;"))
>
>     2) With a stack-allocated value it will segfault immediately.
>
>     (define make-point
>         (c-lambda (int int) struct-point
>           "point a;
>            a.x = ___arg1;
>            a.y = ___arg2;
>            ___result = a;"))
>
>     3) If we give the address of a stack-allocated value to
>     ___result_voidstar the allocation loop is running with constant memory
>     space but the programm will segfault after quiting with CTRL + X.
>
>     (define make-point
>         (c-lambda (int int) struct-point
>           "point a;
>            a.x = ___arg1;
>            a.y = ___arg2;
>            ___result_voidstar = &a;"))
>
>
>     For more details, see discussion:
>     https://mercure.iro.umontreal.ca/pipermail/gambit-list/2013-August/006950.html
>
>
>     Chris
>     _______________________________________________
>     Gambit-list mailing list
>     Gambit-list at iro.umontreal.ca <mailto:Gambit-list at iro.umontreal.ca>
>     https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
>
>




More information about the Gambit-list mailing list