diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-06-06 17:58:06 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-06-06 17:58:06 -0700 |
commit | 16b390a2d811bb0dbe6f8d8bf1cf21cb397d3447 (patch) | |
tree | e8530efaca66c05d712f3238f9066fe4f31fd05f | |
parent | db161112abb1c684bf91b2c434e18b488c0aa2ca (diff) | |
download | txr-16b390a2d811bb0dbe6f8d8bf1cf21cb397d3447.tar.gz txr-16b390a2d811bb0dbe6f8d8bf1cf21cb397d3447.tar.bz2 txr-16b390a2d811bb0dbe6f8d8bf1cf21cb397d3447.zip |
ffi: allow conversion of carray objects under cptr.
* ffi.c (ffi_cptr_put): If the object is not a cptr, try it as
a carray. This requires the tft to have an eltype, requiring
a change in ffi_type_compile.
(ffi_type_compile): When compiling a parametrized cptr object,
we now look up the type symbol as a FFI type, and store the
result as the tft->eltype. If the symbol is not an FFI type,
then this lookup returns nil. If the eltype is non-nil, then
there is the possibility it can match the element type of a
carray.
* txr.1: Documented.
-rw-r--r-- | ffi.c | 11 | ||||
-rw-r--r-- | txr.1 | 34 |
2 files changed, 41 insertions, 4 deletions
@@ -1901,10 +1901,16 @@ static val ffi_bool_rget(struct txr_ffi_type *tft, mem_t *src, val self) #endif -static void ffi_cptr_put(struct txr_ffi_type *tft, val n, mem_t *dst, +static void ffi_cptr_put(struct txr_ffi_type *tft, val ptr, mem_t *dst, val self) { - mem_t *p = cptr_handle(n, tft->tag, self); + mem_t *p = 0; + + if (type(ptr) == CPTR) + p = cptr_handle(ptr, tft->tag, self); + else + p = carray_ptr(ptr, tft->eltype, self); + *coerce(mem_t **, dst) = p; } @@ -3932,6 +3938,7 @@ val ffi_type_compile(val syntax) tft->alloc = ffi_cptr_alloc; tft->free = ffi_noop_free; tft->tag = tag; + tft->eltype = gethash(ffi_typedef_hash, tag); if (cddr(syntax)) goto excess; return type; @@ -74513,7 +74513,10 @@ type is similar to the unparametrized .codn cptr . It also converts between Lisp objects of type .code cptr -and foreign pointers. However, it provides a measure of type safety. +and foreign pointers. Unlike the unparametrized type, it provides a measure of +type safety, and also supports the conversion of +.code carray +objects. When a foreign pointer is converted to a Lisp object under control of the parametrized @@ -74544,7 +74547,34 @@ is specified as .codn nil , then this is precisely equivalent to the unparametrized .code cptr -which doesn't provides the above safety measure. +which doesn't provide the above safety measure. + +A +.code carray +object may also be converted to a foreign pointer under the control of +a parametrized +.code cptr +type. The +.code carray +object's internal pointer becomes the foreign pointer value. +The conversion is only permitted if the following two restrictions are not met, +otherwise an error exception is thrown. +Firstly, the +.meta type-sym +of the +.code cptr +type must be the name of an FFI type, at the time when the +.code cptr +type expression is processed, otherwise the +.code cptr +is not associated with a type. +Secondly, the +.code carray +object being converted must have an element type which matches the +FFI type denoted by the +.code cptr +object's +.metn type-sym . Pointer type safety is useful, because FFI can be used to create bindings to large application programming interfaces (APIs) in which objects of |