[plt-scheme] ffi equivalent of array in struct

From: Danny Yoo (dyoo at hkn.eecs.berkeley.edu)
Date: Mon Apr 24 20:23:40 EDT 2006

>> You can use `make-cstruct-type' with a list of 10 _int values, that 
>> will create a struct type of the desired size.
>> 
> Do I have to list them all? (make-cstruct-type _int _int _int ...) ? The 
> real problem is a struct with 65536 chars in it. I dont want to have to 
> type all those..
>
> Or I suppose I could make cstruct's which contain other cstructs and balloon 
> upto the size I wanted anyway:
> (define 4bytes _int)
> (define 8bytes (make-cstruct-type 4bytes 4bytes))
> (define 16bytes (make-cstruct-type 8bytes 8bytes))
> (define 32bytes (make-cstruct-type 16bytes 16bytes))
> Almost there!
> (define 65536bytes (make-struct-type 32000bytes 32000bytes))


Hi Jon,

This seems repetitive, so maybe a macro will help.

Here's one that I just cooked up (starting to learn about quasiquotation 
now...):

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(module n-bytes mzscheme
   (require (lib "foreign.ss"))
   (require-for-syntax (lib "stx.ss" "syntax"))

   (define 4bytes _int)
   (define 8bytes (make-cstruct-type (list 4bytes 4bytes)))

   (define-for-syntax (multiple-of-four? n)
     (and (number? n) (= 0 (remainder n 4))))

   (define-for-syntax (build-int-stx-list stx n)
     (let loop ([n n]
                [acc #'()])
       (cond
         [(= n 0) acc]
         [else
          (loop (- n 4)
                (quasisyntax/loc stx
                  (_int . #,acc)))])))

   (define-syntax (n-bytes stx)
     (syntax-case stx ()
       [(_ n)
        (cond
          [(multiple-of-four? (syntax-e #'n))
           (quasisyntax/loc stx
             (make-cstruct-type
              (list #,@(build-int-stx-list stx (syntax-e #'n)))))]
          [else
           (raise-syntax-error
            #f
            "expected numeric literal divisible by four"
            stx)])])))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

n-bytes requires a literal number to work.  But if we have this, then we 
can say:

     (define 65536bytes (n-bytes 65536))

without too many problems.


Good luck!


Posted on the users mailing list.