Hi,
I've spent many many frustrating hours trying to talk to a C struct using the FFI. Looking around at other examples, there seem to be many ways of doing this..., but none of them worked for me. In the end I wrote a short example shown below that appears to work. It relies on all the heavy lifting being done in C and just simple wrappers being written in Scheme. As written, I believe it makes Scheme and C share the same struct, no copies being taken (this is crucial for me, as the C code will alter the C struct and likewise my Scheme code will alter it too). Before I go too far with this approach, I just want to check that it is memory safe.
Here it is:
; ;Example where Gambit Scheme and C are sharing the SAME struct in memory using a pointer. ; (c-declare #<<end-of-c-declare typedef struct { int x; int y; } Cstruct;
Cstruct* make_point( int x, int y ) { Cstruct* p = (Cstruct*) malloc(sizeof(Cstruct)); p->x = x; p->y = y; return p; }
int point_x( Cstruct* p ) { return p->x; } int point_y( Cstruct* p ) { return p->y; }
//if you create new memory using malloc you must free it again when you've finished to avoid a dangling pointer memory leak void free_point( Cstruct* p ){free(p);}
end-of-c-declare )
(c-define-type Sstruct* (pointer "Cstruct"))
(define make-point (c-lambda (int int) Sstruct* "make_point")) (define free-point (c-lambda (Sstruct*) void "free_point")) (define point-x (c-lambda (Sstruct*) int "point_x")) (define point-y (c-lambda (Sstruct*) int "point_y"))
(define SchemeStruct (make-point 12345 6789)) (println "p->x in C struct holds the value " (point-x SchemeStruct)) (println "p->y in C struct holds the value " (point-y SchemeStruct)) (free-point SchemeStruct); included for completeness, but not needed because program is ending anyway in this example