Add caveat in unwrapped native handles about defcfn with primitives

This commit is contained in:
Joshua Suskalo 2022-01-18 15:40:31 -06:00
parent 5c560e684d
commit 447117e092

View file

@ -534,12 +534,14 @@ to the user to call `deserialize-from` on that segment with the appropriate
type. type.
### Unwrapped Native Handles ### Unwrapped Native Handles
Sometimes the overhead brought by the automatic serialization and Some native libraries work with handles to large amounts of data at once, making
deserialization from the methods explained so far is too much. In cases like it undesirable to marshal data back and forth from Clojure, both because it's
these, unwrapped native handles are desirable. not necessary to work with the data in Clojure directly, or also because of the
high (de)serialization costs associated with marshaling. In cases like these,
unwrapped native handles are desirable.
The functions `make-downcall` and `make-varargs-factory` are provided to create The functions `make-downcall` and `make-varargs-factory` are also provided to
these raw handles. create raw function handles.
```clojure ```clojure
(def raw-strlen (ffi/make-downcall "strlen" [::mem/c-string] ::mem/long)) (def raw-strlen (ffi/make-downcall "strlen" [::mem/c-string] ::mem/long))
@ -547,7 +549,7 @@ these raw handles.
;; => 5 ;; => 5
``` ```
In these cases, the argument types are expected to exactly match the types With raw handles, the argument types are expected to exactly match the types
expected by the native function. For primitive types, those are primitives. For expected by the native function. For primitive types, those are primitives. For
addresses, that is `MemoryAddress`, and for composite types like structs and addresses, that is `MemoryAddress`, and for composite types like structs and
unions, that is `MemorySegment`. Both `MemoryAddress` and `MemorySegment` come unions, that is `MemorySegment`. Both `MemoryAddress` and `MemorySegment` come
@ -569,6 +571,13 @@ Clojure functions serialized to this type will have their arguments and return
value exactly match the types specified and will not perform any serialization value exactly match the types specified and will not perform any serialization
or deserialization at their boundaries. or deserialization at their boundaries.
One important caveat to consider when writing wrappers for performance-sensitive
functions is that the convenience macro `defcfn` that coffi provides will
already perform no serialization or deserialization on primitive arguments and
return types, so for functions with only primitive argument and return types
there is no performance reason to choose unwrapped native handles over the
convenience macro.
### Data Model ### Data Model
In addition to the macros and functions provided to build a Clojure API for In addition to the macros and functions provided to build a Clojure API for
native libraries, facilities are provided for taking data and loading all the native libraries, facilities are provided for taking data and loading all the