From f7b19fe724fd55d953bd4c7796726cfeaf1a0484 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sat, 20 May 2017 16:58:34 -0700 Subject: ffi: new macro, deffi-var. * lisplib.c (ffi_set_entries): Autload entry for "deffi-var". * share/txr/stdlib/ffi.tl (deffi-var): New macro. * txr.1: Documented. --- lisplib.c | 3 ++- share/txr/stdlib/ffi.tl | 15 +++++++++++++++ txr.1 | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/lisplib.c b/lisplib.c index acc7b6b6..df5e9a93 100644 --- a/lisplib.c +++ b/lisplib.c @@ -524,7 +524,8 @@ static val ffi_set_entries(val dlt, val fun) { val name[] = { lit("with-dyn-lib"), lit("deffi"), lit("deffi-type"), lit("deffi-cb"), - lit("typedef"), lit("sizeof"), lit("ffi"), lit("carray-ref"), + lit("deffi-var"), lit("typedef"), lit("sizeof"), lit("ffi"), + lit("carray-ref"), nil }; set_dlt_entries(dlt, name, fun); diff --git a/share/txr/stdlib/ffi.tl b/share/txr/stdlib/ffi.tl index ce497d17..69a19a1e 100644 --- a/share/txr/stdlib/ffi.tl +++ b/share/txr/stdlib/ffi.tl @@ -96,6 +96,21 @@ (defmacro deffi-cb-unsafe (:form f name rettype argtypes) (sys:deffi-cb-expander f name rettype argtypes nil nil)) +(defmacro deffi-var (:form f name var-expr type) + (let ((var-ref (cond + ((stringp var-expr) + ^(dlsym-checked sys:ffi-lib ,var-expr)) + ((consp var-expr) + (mac-param-bind f (sym ver) var-expr + ^(dlvsym-checked sys:ffi-lib ,sym ,ver))) + (t var-expr))) + (type-sym (gensym "type-")) + (var-sym (gensym "var-"))) + ^(progn + (defvarl ,type-sym (ffi ,type)) + (defvarl ,var-sym (carray-cptr ,var-ref ,type-sym 1)) + (defsymacro ,name (carray-ref ,var-sym 0))))) + (defmacro sizeof (type) (ffi-size (ffi-type-compile type))) diff --git a/txr.1 b/txr.1 index 99f3599b..423fdb8e 100644 --- a/txr.1 +++ b/txr.1 @@ -54686,6 +54686,50 @@ parameter, since unsafe callbacks do not use it. .cble +.coNP Macro @ deffi-var +.synb +.mets (deffi-var < name < var-expr << type ) +.syne +.desc +The +.code deffi-var +macro defines a global symbol macro which expands to an expression +accessing a foreign variable, creating the illusion that the +variable is available as a Lisp variable holding a Lisp data type. + +The +.meta name +argument gives the name of the macro. + +The +.meta var-expr +argument must evaluate to a +.code cptr +object which holds a pointer to the address of the foreign +variable. + +The +.meta type +argument expresses the variable type in FFI type syntax. + +Once the variable is defined, accessing the macro symbol +.meta name +performs a get operation on the foreign variable, yielding +the conversion of that variable to a Lisp value. +An assignment to the symbol performs a put operation, +converting a Lisp object to a value which overwrites +the object. + +Note: FFI memory management is not helpful in the use of +variables. Suppose a string value is +stored in a variable of type +.codn str . +This means that FFI dynamically allocates a buffer which +stores the UTF-8 encoded version of the string, and this +buffer is placed into the foreign variable. +Then suppose another such assignment takes place. +The previous value is simply overwritten without being +freed. .coNP Macro @ typedef .synb .mets (typedef < name << type-syntax ) -- cgit v1.2.3