[gambit-list] Proper usage of ffi structs

Marc Feeley feeley at iro.umontreal.ca
Thu Aug 22 10:53:44 EDT 2013


On 2013-08-22, at 9:20 AM, Mikael <mikael.rcv at gmail.com> wrote:

> Aha.
> 
> Very well, then I guess it's good time to ask Marc how this stuff works really. :))
> 
> 
> Marc, would you feel like enlightening us on this one - how use and reclaim of non-pointered FFI structs works out?
> 

I tested this code and it works fine:


(declare (standard-bindings) (fixnum) (not safe))

(c-declare #<<end-of-c-declare

struct point { int x; int y; };

struct point make_point( int x, int y ) {

  struct point p;
  p.x = x;
  p.y = y;

  return p;
}

end-of-c-declare
)

(c-define-type struct-point (struct "point"))

(define make-point
  (c-lambda (int int) struct-point "make_point"))

(define make-point2 ;; this should be equivalent but triggers a bug in Gambit
  (c-lambda (int int) struct-point
    "struct point p;
     p.x = ___arg1;
     p.y = ___arg2;
     ___result = p;"))

(define (alloc-points times)
  (let loop ((i 0))
     (if (< i times)
       (let ((p (make-point 0 0)))
         (loop (+ i 1))))))

(time (alloc-points 100000000))


Deallocation of the structures is done correctly and there is no memory leak or segmentation faults.  If the return type had been a C++ class, the destructor would have been called just prior to its deallocation by the GC, as expected.

There seems to be a problem however in the "inline" c-lambda form (as used in the definition of make-point2).  The definition should be equivalent to the definition of make-point, but isn't.  That's a bug that I will investigate.

I suggest that for the time being, you avoid using inline c-lambda forms that return structures.  This means you will have to create a C function that returns a structure, and use the plain c-lambda form to interface to that C function.

Marc



More information about the Gambit-list mailing list