[racket] Trouble with C->Racket callbacks passing pointers to arrays

From: Dmitry Pavlov (dpavlov at ipa.nw.ru)
Date: Mon Aug 20 13:56:40 EDT 2012

Matthew,

>> (define _handler (_fun _int _pointer ->  _int))
>
> The `_pointer' C type means a reference to memory that is not managed
> by the GC. Change the `_pointer' above to `_gcpointer', since the
> handler receives a pointer that is managed by the GC.

That makes perfect sense! Thank you very much. Indeed, the example
works fine after I replaced _pointer with _gcpointer.


However, it seems that I have a similar problem with a callback
that fills an array malloc()-ed in the C library, and I am stupid
enough not to understand why it fails, again.
Could you please take a look at this:

int myfunc2 (int length, double *x, int (*filler) (int length, double *arr))
{
    double *buf = (double *)malloc(length * sizeof(double));
    filler(length, buf);
    memcpy(x, buf, length * sizeof(double));
    free(buf);
    return 0;
}


(define _filler (_fun _int _pointer -> _int))
(define-libintegrator myfunc2 (_fun _int _gcpointer _filler -> _int))

(define (make-myfiller)
   (let ((counter 0))
     (lambda (len ptr)
       (printf "fill #~a\n" counter)
       (collect-garbage)
       (set! counter (add1 counter))
       (let ((vec (make-cvector* ptr _double len)))
         (for ((i (in-range len)))
           (cvector-set! vec i (* (add1 i) 5.0))))
       0)))

(define myfiller (make-myfiller))

(define (test2)
   (let ((vec (make-f64vector 3)))
     (f64vector-set! vec 0 1.0)
     (f64vector-set! vec 1 2.0)
     (f64vector-set! vec 2 3.0)
     (myfunc2 3 (f64vector->cpointer vec) myfiller)
     (f64vector->vector vec)))


The very first (test2) call gives '#(1.0 2.0 3.0),
which is incorrect (should be 5,10,15).
Thanks to (collect-garbage) trick, now there is no
need to try N times before it fails...

Best regards,

Dmitry


Posted on the users mailing list.