[racket] passing flvectors to/from C function

From: Dmitry Pavlov (dpavlov at ipa.nw.ru)
Date: Tue Jan 13 17:06:34 EST 2015

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

Posted on the users mailing list.