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