[gambit-list] FFI C struct

sales.creditscore at creditscore.co.nz sales.creditscore at creditscore.co.nz
Mon Apr 22 05:37:46 EDT 2013


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




More information about the Gambit-list mailing list