Fill in section on complex wrappers

This commit is contained in:
Joshua Suskalo 2021-09-25 10:36:43 -05:00
parent 079da412b8
commit a75c1a9c0e

View file

@ -202,7 +202,39 @@ value is being mutated on another thread.
A parallel function `fswap!` is also provided, but it does not provide any A parallel function `fswap!` is also provided, but it does not provide any
atomic semantics either. atomic semantics either.
### TODO Complex Wrappers ### Complex Wrappers
Some functions require more complex code to map nicely to a Clojure function.
The `defcfn` macro provides facilities to wrap the native function with some
Clojure code to make this easier.
```clojure
(defcfn takes-array
"takes_array_with_count" [::ffi/pointer ::ffi/long] ::ffi/void
native-fn
[ints]
(let [arr-len (count ints)
int-array (serialize ints [::ffi/array ::ffi/int arr-len]
(native-fn (ffi/address-of int-array) arr-len))]))
```
The symbol `native-fn` can be any unqualified symbol, and names the native
function being wrapped. It must be called in the function body below if you want
to call the native code.
This `serialize` function has a paired `deserialize`, and allows marshaling
Clojure data back and forth to native data structures.
This can be used to implement out variables often seen in native code.
```clojure
(defcfn out-int
"out_int" [::ffi/pointer] ::ffi/void
native-fn
[i]
(let [int-ptr (serialize i [::ffi/pointer ::ffi/int])]
(native-fn int-ptr)
(deserialize int-ptr [::ffi/pointer ::ffi/int])))
```
### TODO Scopes ### TODO Scopes