[racket] passing flvectors to/from C function
Hello,
I need to pass flvectors to/from C library as "double *" arrays.
Due to the absence of _flvector custom function type in Racket FFI,
and took the challenge of writing one myself.
Below is what I just came up with.
(define (allocate-cvector len)
(cast (malloc _double 'atomic-interior)
_pointer
(_gcable
(_cvector o _double len))))
(define (flvector->cvector/immobile flvec)
(let* ((len (flvector-length flvec))
(cvec (allocate-cvector len)))
(for ((i (in-range len)))
(cvector-set! cvec i (flvector-ref flvec i)))
cvec))
(define (cvector->flvector ptr len)
(let* ((result (make-flvector len)))
(for ((i (in-range 0 len)))
(flvector-set! result i (cvector-ref ptr i)))
result))
(define-fun-syntax _flvector
(syntax-rules (i o io)
[(_ i) (type: _cvector
pre: (x => (flvector->cvector/immobile x)))]
[(_ o n) (type: _cvector
pre: (allocate-cvector n)
post: (x => (cvector->flvector x n)))]
[(_ io) (type: _cvector
bind: tmp
pre: (x => (flvector->cvector/immobile x))
post: (x => (cvector->flvector x (flvector-length tmp))))]
))
Are there any dangerous places in my code? I ask because calling
a number of times a function with just (_flvector i) arguments
causes Racket to crash. I am wondering whether I overlooked
something (which I usually do with the FFI), or I should look
into C code.
It would be nice to know if I am generally on the right track, too.
I noticed the flvector->cpointer transformation in Racket, but
then I went all "oh I can not do that because what if Racket's GC
moves my flvector while the C function is operating with the cpointer"
and decided not to use it.
Best regards,
Dmitry