[racket] FFI for struct that wraps around char array

From: Evgeny Odegov (evgeny-odegov at mail.ru)
Date: Tue Nov 18 11:14:36 EST 2014

Hi,

Version with conversion to/from string:


(define (_string/locale/len n) ; n - bytes, not characters
   (make-ctype (make-array-type _byte n)
               ;->C
               (lambda (in)
                 (cond
                   [(not in)
                    (make-bytes n)]
                   [(string? in)
                    (define bs (string->bytes/locale in))
                    (cond
                      [((bytes-length bs) . >= . n) ; len+1 > n
                       (error '_string/locale/len "string is too 
long\n~v" in)]
                      [else
                       (define out (make-bytes n))
                       (bytes-copy! out 0 bs)
                       out])]
                   [else
                    (error '_string/locale/len "expected string? or #f, 
got ~v" in)]))
               ;->racket
               (lambda (in)
                 (define bs (make-sized-byte-string in n))
                 (define len
                   (for/fold ([acc 0])
                     ([b (in-bytes bs)]
                      [pos (in-naturals)]
                      #:final (zero? b))
                     pos))
                 (define sub-bs (subbytes bs 0 len))
                 (bytes->string/locale sub-bs))))


I would use this:

(define camera-text-size (* 32 1024))
(define-cstruct _CameraText ([value (_string/locale/len camera-text-size)]))


For passing as a parameter to 'gp_camera_get_about':

(define cam-text (make-CameraText #f))




13.11.2014 20:00, Bartosz Przygoda пишет:
> Hello,
>
> I'm trying to make racket bindings for libgphoto2. Its API uses CameraText
> struct for outputting strings, which just wraps char array.
>
> My first attempt was:
>
> (define _Camera-ptr (_cpointer 'Camera))
> (define _CameraText-ptr (_cpointer 'CameraText))
>
>
> (define-gphoto gp_camera_get_about
>    (_fun _Camera-ptr (v : _CameraText-ptr) _GPContext-ptr
>       -> _int))
>
> But this was giving me segfaults (not to mention the pointer here is opaque
> and there are no getter functions in API).
>
> Later on I've stumbled across
> https://github.com/dyoo/ffi-tutorial/blob/master/ffi/tutorial/examples/struct-with-array/struct-with-array.rkt
> so I've tried this:
>
> (define _Camera-ptr (_cpointer 'Camera))
>
> (define camera-text-size (* 32 1024))
> (define-cstruct _CameraText ([text (_bytes/len (camera-text-size))]))
>
> (define-gphoto gp_camera_get_about
>    (_fun _Camera-ptr (v : _CameraText-pointer) _GPContext-ptr
>       -> _int))
>
> (Where bytes/len is helper taken from that example)
>
> How can I initialize this struct to mimic C CameraText txt;? Is there some
> better way to handle char arrays (and converting them to strings) than
> _byte array? Or should I go with something like (but this was segfaulting
> as well):
>
> (define-cstruct _CameraText ([text _string]))
>
>
>
> ____________________
>    Racket Users list:
>    http://lists.racket-lang.org/users

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20141118/90d7b205/attachment.html>

Posted on the users mailing list.