[racket] Trouble with C->Racket callbacks passing pointers to arrays
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