Skip to content

ffi2 #5479

@mflatt

Description

@mflatt

This issue is a place to continue the discussion from PR #5471.

I don't have a better name than ffi2, so the name of the library has not changed, so far.

The state since the initial PR and discussion there:

  • define-ffi2-type now supports type constructors that are parameterized over values.
  • define-ffi2-type-syntax supports macros for type positions.
  • -> supports much of the argument and result sublanguage of _fun from ffi/unsafe, but it stops short of supporting things like _ptr.
  • API documentation is intended to be complete for everything implemented so far.

Here's the curses example from the ffi/unsafe documentation ported to ffi2.

#lang racket/base
(require ffi2)
 
(define-ffi2-definer define-curses
  #:lib (ffi2-lib "libcurses"))

(define-ffi2-type WINDOW_t* void_t*)

(define-curses initscr (-> WINDOW_t*))

(define-ffi2-type (ok_int_t who) int_t
  #:c->racket (lambda (v)
                (unless (zero? v)
                  (error who "failed: ~a" v))))
 
(define-curses waddstr (WINDOW_t* string_t . -> . (ok_int_t 'waddstr)))
(define-curses wrefresh (WINDOW_t* . -> . (ok_int_t 'wrefresh)))
(define-curses endwin (-> (ok_int_t 'endwin)))

(define-ffi2-type mmask_t ulong_t)
(define-ffi2-type mmask_t* (array mmask_t *))
;; yes, I've noticed that this is prettier with `(_ptr o _mmask)`, but it seems
;; like a lot of extra machinery to get that one feature
(define-curses mousemask (mmask_t [old : mmask_t* = (ffi2-malloc mmask_t)]
                                  . -> . [r : mmask_t]
                                  #:result (values (ffi2-ref old mmask_t) r)))
(define BUTTON1_CLICKED 4)

(define-ffi2-type MEVENT_t (struct
                             [id short_t]
                             [x int_t]
                             [y int_t]
                             [z int_t]
                             [bstate mmask_t]))
(define-curses getmouse ([m : MEVENT_t* = (MEVENT_t 0 0 0 0 0)]
                         . -> . (r : int_t)
                         #:result (and (zero? r) m)))
 
(define-curses wgetnstr (WINDOW_t* ptr_t int_t . -> . int_t))

(define win (initscr))
(define-values (old supported) (mousemask BUTTON1_CLICKED))
(void (waddstr win "Hello"))
(void (wrefresh win))
(sleep 1)

(define SIZE 256)
(define buffer (ffi2-malloc SIZE))
(ffi2-memset buffer 0 SIZE)
 
(void (wgetnstr win buffer (sub1 SIZE)))

(define m (getmouse))
(when m
  (waddstr win (format "at ~a,~a"
                       (MEVENT_t-x m)
                       (MEVENT_t-y m)))
  (wrefresh win)
  (sleep 1))

(void (endwin))

(ffi2-cast buffer #:to string_t)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions