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
____________________
 Racket Users list:
 http://lists.racket-lang.org/users

Reply via email to