Le 17/06/2017 à 20:53, Matt Wette a écrit :
The following seems to be a Guile architecture wrt how FFI-based interfaces should be implemented. I am working on a ffi-helper: a program that will read in a C dot-h file and generate a Guile dot-scm file which defines a module to provide hooks into the associated C library. I am looking for concurrence on the following: Enums and #defines: Here is how I plan to handle enums and #defines 1) visibility to values is provided through an access function e.g., (get-foo-val ‘ABC) not ABC via (define ABC 1) 2) only #defined symbols that evaluate to constants (e.g., 123, “ABC”, etc) will be visible 3) all enum-defined symbols will be visible 4) for enum typedefs and enum def's I will provide (but not export) wrappers so that functions that take an enum type as argument will require the symbolic form e.g., if signature is typedef enum { ABC = 1 } foo_enum_t; typedef enum { OK = 0, ERROR = 1 } foo_status_t; foo_status_t bar(foo_enum_t flag) then the guile un-wrapper/wrapper will convert symbols<=>ints to allow users code to look like (bar ‘ABC) => ‘OK Optionally, the un-wrappers could be coded tolerate integers. OK? Matt P.S. auto-generated and hand-clean-up (i.e., not fully working yet) ;; access to #define constants: (define cairo-svg-def-val (let ((deftab '((CAIRO_VERSION_MAJOR . 1) (CAIRO_VERSION_MINOR . 14) ... (CAIRO_SVG_VERSION_1_1 . 1) (CAIRO_SVG_VERSION_1_2 . 2)))) (lambda (k) (assq-ref deftab k)))) (export cairo-svg-def-val) ;; typedef struct _cairo_font_options cairo_font_options_t; (define-std-pointer-wrapper cairo_font_options_t*) ;; typedef enum _cairo_status cairo_status_t; (define wrap-cairo_status_t (let ((vnl '((0 . CAIRO_STATUS_SUCCESS) (1 . CAIRO_STATUS_NO_MEMORY) ... (38 . CAIRO_STATUS_JBIG2_GLOBAL_MISSING) (39 . CAIRO_STATUS_LAST_STATUS)))) (lambda (code) (assq-ref vnl code)))) (define unwrap-cairo_status_t (let ((nvl '((CAIRO_STATUS_SUCCESS . 0) (CAIRO_STATUS_NO_MEMORY . 1) ... (CAIRO_STATUS_JBIG2_GLOBAL_MISSING . 38) (CAIRO_STATUS_LAST_STATUS . 39)))) (lambda (name) (assq-ref nvl name)))) (define wrap-enum-_cairo_status (let ((vnl '((0 . CAIRO_STATUS_SUCCESS) (1 . CAIRO_STATUS_NO_MEMORY) (2 . CAIRO_STATUS_INVALID_RESTORE) ... (38 . CAIRO_STATUS_JBIG2_GLOBAL_MISSING) (39 . CAIRO_STATUS_LAST_STATUS)))) (lambda (code) (assq-ref vnl code)))) (define unwrap-enum-_cairo_status (let ((nvl '((CAIRO_STATUS_SUCCESS . 0) (CAIRO_STATUS_NO_MEMORY . 1) ... (CAIRO_STATUS_JBIG2_GLOBAL_MISSING . 38) (CAIRO_STATUS_LAST_STATUS . 39)))) (lambda (name) (assq-ref nvl name)))) ;; cairo_status_t cairo_font_options_status(cairo_font_options_t *options); (define cairo_font_options_status (let ((f (ffi:pointer->procedure ffi:int (lib-func "cairo_font_options_status") (list '*)))) (lambda (options) (let ((~options (unwrap-cairo_font_options_t* options))) (wrap-cairo_status_t (f ~options)))))) (export cairo_font_options_status)
It makes sens to me.