[racket] passing flvectors to/from C function

From: Dmitry Pavlov (dpavlov at ipa.nw.ru)
Date: Wed Jan 14 02:40:04 EST 2015

I have just found that it crashes because I forgot to pass
vector length to malloc.

(define (allocate-cvector len)
    (cast (malloc  len _double 'atomic-interior)
           _pointer
           (_gcable
            (_cvector o _double len))))

After the fix, crashes are gone.
I am still not sure that my code is not overcomplicated, though.

Best regards,

Dmitry Pavlov


On 01/14/2015 01:06 AM, Dmitry Pavlov wrote:
> 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.