diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-05-20 16:58:34 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-05-20 16:58:34 -0700 |
commit | a7517ded29c1c3bf8a50b2ce690bcfac575db350 (patch) | |
tree | 5223e5bde27713fa354f4a07f69c610b8de1e224 | |
parent | 765548d93ca58734805e2932565398fe31d5a517 (diff) | |
download | txr-a7517ded29c1c3bf8a50b2ce690bcfac575db350.tar.gz txr-a7517ded29c1c3bf8a50b2ce690bcfac575db350.tar.bz2 txr-a7517ded29c1c3bf8a50b2ce690bcfac575db350.zip |
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.
-rw-r--r-- | lisplib.c | 3 | ||||
-rw-r--r-- | share/txr/stdlib/ffi.tl | 15 | ||||
-rw-r--r-- | txr.1 | 44 |
3 files changed, 61 insertions, 1 deletions
@@ -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))) @@ -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 ) |