[plt-scheme] Specifying a callback that takes a f64vector

From: Noel Welsh (noelwelsh at gmail.com)
Date: Fri May 1 07:24:31 EDT 2009

Well, I'm no closer to understanding how the _f64vector type works,
but I've implemented my own which does the job.  Code below in case
anyone ever has use for it.

The main problem is I don't understand the FFI model (and I'm not
finding the docs useful). For example, I don't understand how I can
define a function in Scheme with a f64vector parameter, and get C code
to call this function. (_f64vector i) doesn't allow me to specify a
length, and I just get these "Can't convert a C pointer to f64vector"
errors at runtime.

BTW, the _f64vector error messages are bad. I ended up hacking
foreign.ss to understand what is going on. For example, this:

> (_f64vector i 2)
reference to undefined identifier: i

is a pretty poor user experience; the docs do not indicate this is not allowed.


;; (hashof f64vector cpointer)
(define useful-f64vector-map (make-hash))

(define (useful-f64vector-ref v)
  (hash-ref useful-f64vector-map v
            (lambda (v)
              (error (format "No ptr value associated with f64vector
~a\n" v)))))

(define (useful-f64vector-set! v ptr)
  (hash-set! useful-f64vector-map v ptr))

(define ((useful-f64vector-update-C! length) v)
  (let ([ptr (useful-f64vector-ref v)])
    (for ([idx (in-range length)])
         (ptr-set! ptr _double idx (f64vector-ref v idx)))

;; Define an f64vector C type that can actually be used as
;; an input and output parameter, rather than the bizarre
;; implementation given with the FFI.
(define (useful-f64vector length)
  (_cpointer 'useful-f64vector
             ;; Scheme -> C
             (useful-f64vector-update-C! length)
             ;; C -> Scheme
             (lambda (ptr)
               (let ([v (make-f64vector length)])
                 (for ([offset (in-range length)])
                   (f64vector-set! v offset (ptr-ref ptr _double offset)))
                 (useful-f64vector-set! v ptr)

Posted on the users mailing list.