Liking cljdoc? Tell your friends :D

babashka.ffi

clj

Call functions in native shared libraries.

Load a library, bind C functions with explicit argument and return types, and manage native memory:

(require '[babashka.ffi :as ffi])
(ffi/load-system-library "sqlite3")
(def sqlite3-open (ffi/cfn "sqlite3_open" [:string :pointer] :int))
(with-open [arena (ffi/confined-arena)]
  (let [pp (ffi/alloc arena :pointer)]
    (sqlite3-open "x.db" pp)
    (ffi/read pp :pointer)))

Every allocation belongs to an arena. The arena controls the lifetime of the memory.

Use these type keywords:

:void
:int :uint :long :ulong :int8 :uint8 :int16 :uint16 :int32
:uint32 :int64 :uint64 :size_t :ssize_t :char :byte
:bool :pointer :string :double :float

A pointer is a native java.lang.foreign.MemorySegment with a size. read and write check each access against this size. Pointers from C have size zero. Use reinterpret to specify their size before access.

:bool represents a one-byte C boolean and returns true or false. For predicates declared to return C int, use :int and test with zero?.

A layout describes memory: [:struct [[name type] ...]] for a struct and [:array type n] for a fixed array. read returns a struct as a map and an array as a vector. write accepts a map for a struct and a sequence for an array. A field of a struct can be either, so char name[32] is [:name [:array :char 32]].

[:union [[name type] ...]] describes a C union. read returns a union as a pointer to its bytes. Read the active member from that pointer using its type. write takes a [member value] pair. Unions cannot be passed by value.

Use place to select a layout member by name or by a path of names and array indices. Pass the result to read or write instead of a type. A place stores the member's offset and type.

read-array and write-array copy elements of one scalar type between native memory and a Java array of that width, as a memcpy.

Use a layout in a function signature to pass or return a struct by value. Represent struct values as maps:

(ffi/defcfn c-div "div" [:int :int] [:struct [[:quot :int] [:rem :int]]])
(c-div 7 2)   ;=> {:quot 3 :rem 1}

On the JVM, struct calls use the FFM linker and need only the JDK. Native images use libffi for struct calls. See doc/guide.md.

Native images compile a fixed set of fast call shapes: up to six arguments, at most three mixed floating-point arguments or four of the same floating-point type, up to 10 integer or pointer arguments, and a :float return with up to four arguments. A fixed signature outside this set requires libffi. Binding fails if libffi is unavailable.

Native images use libffi for every variadic call. Without libffi, a variadic call throws. In a native image, callbacks support up to four arguments with at most two :double arguments, or up to six integer and pointer arguments. Callbacks do not support :float. The callback return type must be :void, an integer type, :pointer, or :double. Argument order does not affect these limits. See doc/guide.md for details and workarounds.

Add :& to argtypes to declare a variadic C function. The types before :& are the fixed parameters. Types after :& declare the tail once. With no types after :&, each call infers the tail types from its values. Integers and pointers use 64-bit integers. C promotion converts floats to doubles. Strings use C strings:

(ffi/defcfn c-open "open" [:string :int :&] :int)
(c-open path O_RDONLY)         ; empty tail
(c-open path flags 0644)       ; one-int tail, same binding
Call functions in native shared libraries.

Load a library, bind C functions with explicit argument and return types,
and manage native memory:

    (require '[babashka.ffi :as ffi])
    (ffi/load-system-library "sqlite3")
    (def sqlite3-open (ffi/cfn "sqlite3_open" [:string :pointer] :int))
    (with-open [arena (ffi/confined-arena)]
      (let [pp (ffi/alloc arena :pointer)]
        (sqlite3-open "x.db" pp)
        (ffi/read pp :pointer)))

Every allocation belongs to an arena. The arena controls the lifetime of
the memory.

Use these type keywords:

    :void
    :int :uint :long :ulong :int8 :uint8 :int16 :uint16 :int32
    :uint32 :int64 :uint64 :size_t :ssize_t :char :byte
    :bool :pointer :string :double :float

A pointer is a native java.lang.foreign.MemorySegment with a size. read and
write check each access against this size. Pointers from C have size zero.
Use reinterpret to specify their size before access.

:bool represents a one-byte C boolean and returns true or false.
For predicates declared to return C int, use :int and test with zero?.

A layout describes memory: [:struct [[name type] ...]] for a struct and
[:array type n] for a fixed array. read returns a struct as a map and an
array as a vector. write accepts a map for a struct and a sequence for an
array. A field of a struct can be either, so `char name[32]` is
[:name [:array :char 32]].

[:union [[name type] ...]] describes a C union. read returns a union as a
pointer to its bytes. Read the active member from that pointer using its
type. write takes a [member value] pair. Unions cannot be passed by value.

Use place to select a layout member by name or by a path of names and array
indices. Pass the result to read or write instead of a type. A place stores
the member's offset and type.

read-array and write-array copy elements of one scalar type between
native memory and a Java array of that width, as a memcpy.

Use a layout in a function signature to pass or return a struct by value.
Represent struct values as maps:

    (ffi/defcfn c-div "div" [:int :int] [:struct [[:quot :int] [:rem :int]]])
    (c-div 7 2)   ;=> {:quot 3 :rem 1}

On the JVM, struct calls use the FFM linker and need only the JDK. Native
images use libffi for struct calls. See doc/guide.md.

Native images compile a fixed set of fast call shapes: up to six
arguments, at most three mixed floating-point arguments or four of the
same floating-point type, up to 10 integer or pointer arguments, and a
:float return with up to four arguments. A fixed signature outside this
set requires libffi. Binding fails if libffi is unavailable.

Native images use libffi for every variadic call. Without libffi, a
variadic call throws. In a native image, callbacks support up to four
arguments with at most two :double arguments, or up to six
integer and pointer arguments. Callbacks do not support :float. The
callback return type must be :void, an integer type, :pointer, or :double.
Argument order does not affect these limits. See doc/guide.md for details
and workarounds.

Add :& to argtypes to declare a variadic C function. The types before :& are
the fixed parameters. Types after :& declare the tail once. With no types
after :&, each call infers the tail types from its values.
Integers and pointers use 64-bit integers. C promotion converts floats to
doubles. Strings use C strings:

    (ffi/defcfn c-open "open" [:string :int :&] :int)
    (c-open path O_RDONLY)         ; empty tail
    (c-open path flags 0644)       ; one-int tail, same binding
cljs

Call functions in native shared libraries with node:ffi on Node.js.

Use the same names and argument order as the JVM namespace:

(require '[babashka.ffi :as ffi])
(ffi/load-system-library "sqlite3")
(def sqlite3-open (ffi/cfn "sqlite3_open" [:string :pointer] :int))
(ffi/with-open [arena (ffi/confined-arena)]
  (let [pp (ffi/alloc arena :pointer)]
    (sqlite3-open "x.db" pp)
    (ffi/read pp :pointer)))

Needs Node.js 26.1 or newer. Runs under nbb, ClojureScript and shadow-cljs. A ClojureScript compile needs JDK 25 or newer, because the macros come from ffi.clj.

Use these type keywords:

:void
:int :uint :long :ulong :int8 :uint8 :int16 :uint16 :int32
:uint32 :int64 :uint64 :size_t :ssize_t :char :byte
:bool :pointer :string :double :float

A pointer is a Pointer: an address with a size and the arena that owns it. read and write check each access against this size. Pointers from C have size zero. reinterpret specifies their size before access.

A 64-bit integer returns as a number when it is a safe integer, otherwise as a bigint. Arguments accept either.

Use ffi/with-open to close an arena. It closes the arena when the body returns, so do not return a promise that still uses the arena.

Layouts, place, read-array, write-array, copy and clone work as on the JVM. read-array returns a typed array.

node:ffi does not support these, and cfn throws for each:

  • a struct by value in a signature
  • a variadic signature, :&
  • a function pointer as the symbol. Bind a function by name.
Call functions in native shared libraries with node:ffi on Node.js.

Use the same names and argument order as the JVM namespace:

    (require '[babashka.ffi :as ffi])
    (ffi/load-system-library "sqlite3")
    (def sqlite3-open (ffi/cfn "sqlite3_open" [:string :pointer] :int))
    (ffi/with-open [arena (ffi/confined-arena)]
      (let [pp (ffi/alloc arena :pointer)]
        (sqlite3-open "x.db" pp)
        (ffi/read pp :pointer)))

Needs Node.js 26.1 or newer. Runs under nbb, ClojureScript and
shadow-cljs. A ClojureScript compile needs JDK 25 or newer, because the
macros come from ffi.clj.

Use these type keywords:

    :void
    :int :uint :long :ulong :int8 :uint8 :int16 :uint16 :int32
    :uint32 :int64 :uint64 :size_t :ssize_t :char :byte
    :bool :pointer :string :double :float

A pointer is a Pointer: an address with a size and the arena that owns it.
read and write check each access against this size. Pointers from C have
size zero. reinterpret specifies their size before access.

A 64-bit integer returns as a number when it is a safe integer, otherwise
as a bigint. Arguments accept either.

Use ffi/with-open to close an arena. It closes the arena when the body returns, so do not return
a promise that still uses the arena.

Layouts, place, read-array, write-array, copy and clone work as on the
JVM. read-array returns a typed array.

node:ffi does not support these, and cfn throws for each:

- a struct by value in a signature
- a variadic signature, :&
- a function pointer as the symbol. Bind a function by name.
raw docstring

addressclj/s≠

(address p)
clj

Returns the native address of pointer p as a Clojure long.

Returns the native address of pointer p as a Clojure long.
cljs

Returns the native address of pointer p: a number when it is a safe integer, else a bigint.

Returns the native address of pointer p: a number when it is a safe
integer, else a bigint.
source (clj)source (cljs)raw docstring

alignofclj/s

(alignof t)

Returns the alignment, in bytes, of type keyword t or of a struct layout.

Returns the alignment, in bytes, of type keyword t or of a struct layout.
source (clj)source (cljs)raw docstring

allocclj/s≠

(alloc arena n)
(alloc arena n alignment)
clj

Allocates zeroed native memory in arena and returns its pointer. n is an integer byte count, a type keyword, or a struct layout.

Use a confined arena for access from one thread or a shared arena for access from multiple threads. Closing the arena releases its memory.

A type or layout uses natural alignment. An integer byte count uses alignment 16. Specify an alignment to override this value.

For memory allocated by C, bind the allocator with cfn and release the result with the matching C deallocator.

CAUTION: Do not close the arena while C uses its memory. C can access released memory.

Allocates zeroed native memory in arena and returns its pointer.
n is an integer byte count, a type keyword, or a struct layout.

Use a confined arena for access from one thread or a shared arena for
access from multiple threads. Closing the arena releases its memory.

A type or layout uses natural alignment. An integer byte count uses
alignment 16. Specify an alignment to override this value.

For memory allocated by C, bind the allocator with cfn and release the
result with the matching C deallocator.

CAUTION: Do not close the arena while C uses its memory.
C can access released memory.
cljs

Allocates zeroed native memory in arena and returns its pointer. n is an integer byte count, a type keyword, or a struct layout.

A type or layout uses natural alignment. An integer byte count uses alignment 16. Specify an alignment, a power of two, to override this value.

There is no unscoped form. If C allocates the memory, bind its allocator with cfn. Release the result with the matching C deallocator.

CAUTION: Do not close the arena while C uses its memory.

Allocates zeroed native memory in arena and returns its pointer.
n is an integer byte count, a type keyword, or a struct layout.

A type or layout uses natural alignment. An integer byte count uses
alignment 16. Specify an alignment, a power of two, to override this value.

There is no unscoped form. If C allocates the memory, bind its allocator with
cfn. Release the result with the matching C deallocator.

CAUTION: Do not close the arena while C uses its memory.
source (clj)source (cljs)raw docstring

auto-arenaclj/s≠

(auto-arena)
clj

Returns an arena that the garbage collector manages. Keep the arena reachable while C uses its pointers. You cannot close it.

Returns an arena that the garbage collector manages.
Keep the arena reachable while C uses its pointers. You cannot close it.
cljs

Returns an arena that the garbage collector manages. It releases an allocation when no pointer to it is reachable. You cannot close it.

Returns an arena that the garbage collector manages. It releases an
allocation when no pointer to it is reachable. You cannot close it.
source (clj)source (cljs)raw docstring

byte-bufferclj/s≠

(byte-buffer p n)
clj

Returns a java.nio.ByteBuffer view of n bytes of native memory at pointer p. The buffer and native memory share the same bytes.

CAUTION: Do not use the buffer after you release the native memory. An invalid memory access can stop the process.

The byte order is big-endian, as it is for each new ByteBuffer. If you need a different byte order, set it with .order.

Returns a java.nio.ByteBuffer view of n bytes of native memory at pointer p.
The buffer and native memory share the same bytes.

CAUTION: Do not use the buffer after you release the native memory. An
invalid memory access can stop the process.

The byte order is big-endian, as it is for each new ByteBuffer. If you need a
different byte order, set it with .order.
cljs

Returns a Buffer view of n bytes of native memory at pointer p. The Buffer and native memory share the same bytes.

CAUTION: Do not use the Buffer after you release the native memory. An invalid memory access can stop the process.

Returns a Buffer view of n bytes of native memory at pointer p. The Buffer
and native memory share the same bytes.

CAUTION: Do not use the Buffer after you release the native memory. An
invalid memory access can stop the process.
source (clj)source (cljs)raw docstring

callbackclj/s≠

(callback arena f argtypes rettype)
clj

Creates a C function pointer that invokes f. arena owns the pointer, which is valid until the arena releases it. argtypes and rettype use the cfn type keywords. f receives :pointer arguments as zero-size pointers and :bool arguments as booleans. Numeric arguments are passed as numbers. For a :pointer return, f must return a pointer or nil for NULL.

Choose the arena for the thread that calls back:

(ffi/callback (ffi/shared-arena) f [:pointer] :void)

A shared arena allows C to invoke the callback from any thread, including a thread that your code did not create. Use it for asynchronous callbacks, such as event-loop notifications. A confined arena accepts a call from its own thread only. Use it for synchronous callbacks, such as a comparison function. A global arena never releases the pointer.

An automatic arena releases the pointer once the pointer itself becomes unreachable. The garbage collector cannot see the copy that C holds. Use an automatic arena only when your reference outlives every call that C can make.

CAUTION: Unregister the callback before its arena releases the pointer. Catch exceptions inside f. An uncaught exception can stop the process.

Creates a C function pointer that invokes f. arena owns the pointer, which
is valid until the arena releases it.
argtypes and rettype use the cfn type keywords. f receives :pointer arguments
as zero-size pointers and :bool arguments as booleans. Numeric arguments
are passed as numbers. For a :pointer return, f must return a pointer or
nil for NULL.

Choose the arena for the thread that calls back:

    (ffi/callback (ffi/shared-arena) f [:pointer] :void)

A shared arena allows C to invoke the callback from any thread, including a
thread that your code did not create. Use it for asynchronous callbacks, such
as event-loop notifications. A confined arena accepts a call from its own
thread only. Use it for synchronous callbacks, such as a comparison
function. A global arena never releases the pointer.

An automatic arena releases the pointer once the pointer itself becomes
unreachable. The garbage collector cannot see the copy that C holds. Use an
automatic arena only when your reference outlives every call that C can make.

CAUTION: Unregister the callback before its arena releases the pointer.
Catch exceptions inside f. An uncaught exception can stop the process.
cljs

Creates a C function pointer that invokes f. arena owns the pointer, which is valid until the arena releases it. There is no separate release function. argtypes and rettype use the cfn type keywords. f receives :pointer arguments as zero-size pointers and :bool arguments as booleans. For a :pointer return f returns a pointer, or nil for null.

C must call the pointer on the JavaScript thread. f must not throw and must not return a promise.

The global arena never releases the pointer. An automatic arena releases it once the pointer itself becomes unreachable. The garbage collector cannot see the copy that C holds.

CAUTION: Unregister the callback before its arena releases the pointer.

Creates a C function pointer that invokes f. arena owns the pointer, which
is valid until the arena releases it. There is no separate release function.
argtypes and rettype use the cfn type keywords. f receives :pointer
arguments as zero-size pointers and :bool arguments as booleans. For a
:pointer return f returns a pointer, or nil for null.

C must call the pointer on the JavaScript thread. f must not throw and
must not return a promise.

The global arena never releases the pointer. An automatic arena releases
it once the pointer itself becomes unreachable. The garbage collector
cannot see the copy that C holds.

CAUTION: Unregister the callback before its arena releases the pointer.
source (clj)source (cljs)raw docstring

cfnclj/s≠

(cfn sym argtypes rettype)
(cfn lib sym argtypes rettype)
clj

Creates a Clojure function that calls the C function sym. sym is a C symbol name or a function pointer. argtypes is a vector of argument types. rettype is the return type. Use type keywords for scalars and layouts for structs passed by value. Struct values are maps of their fields. Struct calls require libffi in a native image and only the JDK on the JVM.

Use a function pointer for a function that has no exported name. The pointer can come from a loader, C function, struct field, find-symbol, or callback.

A library value limits the search to one library and its dependencies. Without a library value, cfn searches all loaded libraries. Then it searches the default system lookup. The first call resolves the symbol. You can create the binding before you load its library.

A :& in argtypes declares a variadic C function. The types before :& are the fixed parameters. Types after :& declare the variadic argument types. With no types after :&, each call infers them from its values.

Creates a Clojure function that calls the C function sym. sym is a C symbol
name or a function pointer. argtypes is a vector of argument types. rettype
is the return type. Use type keywords for scalars and layouts for structs
passed by value. Struct values are maps of their fields. Struct calls
require libffi in a native image and only the JDK on the JVM.

Use a function pointer for a function that has no exported name. The pointer
can come from a loader, C function, struct field, find-symbol, or callback.

A library value limits the search to one library and its dependencies.
Without a library value, cfn searches all loaded libraries. Then it searches
the default system lookup. The first call resolves the symbol. You can
create the binding before you load its library.

A :& in argtypes declares a variadic C function. The types before :& are
the fixed parameters. Types after :& declare the variadic argument types.
With no types after :&, each call infers them from its values.
cljs

Creates a function that calls the C function sym. sym is a C symbol name. argtypes is a vector of type keywords. rettype is a type keyword.

A library value limits the search to one library and its dependencies. Without a library value, cfn searches all loaded libraries. Then it searches the default system lookup. The first call resolves the symbol. You can create the binding before you load its library.

node:ffi does not pass a struct by value, make a variadic call or call through a function pointer. cfn throws for each when the binding is made.

Creates a function that calls the C function sym. sym is a C symbol name.
argtypes is a vector of type keywords. rettype is a type keyword.

A library value limits the search to one library and its dependencies.
Without a library value, cfn searches all loaded libraries. Then it searches
the default system lookup. The first call resolves the symbol. You can
create the binding before you load its library.

node:ffi does not pass a struct by value, make a variadic call or call
through a function pointer. cfn throws for each when the binding is made.
source (clj)source (cljs)raw docstring

cloneclj/s

(clone arena src)

Allocates a copy of pointer src in arena with the same size and returns the new pointer. Use reinterpret to specify a size for pointers from C.

Allocates a copy of pointer src in arena with the same size and returns
the new pointer. Use reinterpret to specify a size for pointers from C.
source (clj)source (cljs)raw docstring

confined-arenaclj/s≠

(confined-arena)
clj

Returns an arena for one thread. Create this arena in with-open to release its memory.

Returns an arena for one thread.
Create this arena in with-open to release its memory.
cljs

Returns an arena for one thread. Create this arena in ffi/with-open to release its memory.

Returns an arena for one thread.
Create this arena in ffi/with-open to release its memory.
source (clj)source (cljs)raw docstring

copyclj/s

(copy src dst)
(copy src dst n)

Copies bytes from pointer src to pointer dst. Without n, copies the byte size of src. dst must be at least that large. With n, copies n bytes. Returns nil.

Use reinterpret to specify a size for pointers from C. To copy into the middle of dst, slice it first:

(ffi/copy src (ffi/slice dst 16) n)

Supports overlapping regions, as with memmove.

Copies bytes from pointer src to pointer dst. Without n, copies the byte
size of src. dst must be at least that large. With n, copies n bytes.
Returns nil.

Use reinterpret to specify a size for pointers from C. To copy into the
middle of dst, slice it first:

    (ffi/copy src (ffi/slice dst 16) n)

Supports overlapping regions, as with memmove.
source (clj)source (cljs)raw docstring

defcfnclj/s≠macro

clj
(defcfn name docstring? attr-map? sym argtypes rettype)
(defcfn name docstring? attr-map? sym argtypes rettype native-fn & fn-tail)

Defines name as a C function binding created by cfn:

(defcfn sqlite3-open "sqlite3_open" [:string :pointer] :int)

(defcfn sqlite3-open
  "Opens the database at path, storing the handle in out-param pp."
  "sqlite3_open" [:string :pointer] :int)

An optional docstring and attribute map can precede the C symbol, argument types, and return type. Preserves metadata on name, including ^:private.

The :library key in the attribute map selects a library for cfn:

(def sqlite (delay (ffi/load-library (extract-bundled-library!))))
(defcfn sqlite3-open {:library sqlite} "sqlite3_open"
  [:string :pointer] :int)

The value can be a library map or a function that returns one. It can also be an IDeref object that holds a library map.

Without :library, a binding searches all loaded libraries. Then it searches the default system lookup. A system library with the same name can supply the symbol.

The wrapper form binds the raw C function to a local name and defines name as the wrapper:

(defcfn open-db
  "sqlite3_open_v2" [:string :pointer :int :string] :int
  open-native
  [filename flags]
  (with-open [arena (ffi/confined-arena)]
    (let [pdb (ffi/alloc arena :pointer)
          code (open-native filename pdb flags nil)]
      (if (zero? code)
        (ffi/read pdb :pointer)
        (throw (ex-info "open failed" {:code code}))))))

The symbol after the return type names the raw binding. Only the wrapper body can use this name. The forms after the raw name are a normal fn tail. The wrapper can have multiple arities. Its argument lists can differ from the C function. The raw name does not enter the namespace. The wrapper form needs a literal argtypes vector. Only the plain form accepts an argtypes expression.

Defines name as a C function binding created by cfn:

    (defcfn sqlite3-open "sqlite3_open" [:string :pointer] :int)

    (defcfn sqlite3-open
      "Opens the database at path, storing the handle in out-param pp."
      "sqlite3_open" [:string :pointer] :int)

An optional docstring and attribute map can precede the C symbol, argument
types, and return type. Preserves metadata on name, including ^:private.

The :library key in the attribute map selects a library for cfn:

    (def sqlite (delay (ffi/load-library (extract-bundled-library!))))
    (defcfn sqlite3-open {:library sqlite} "sqlite3_open"
      [:string :pointer] :int)

The value can be a library map or a function that returns one. It can also
be an IDeref object that holds a library map.

Without :library, a binding searches all loaded libraries. Then it searches
the default system lookup. A system library with the same name can supply
the symbol.

The wrapper form binds the raw C function to a local name and defines name
as the wrapper:

    (defcfn open-db
      "sqlite3_open_v2" [:string :pointer :int :string] :int
      open-native
      [filename flags]
      (with-open [arena (ffi/confined-arena)]
        (let [pdb (ffi/alloc arena :pointer)
              code (open-native filename pdb flags nil)]
          (if (zero? code)
            (ffi/read pdb :pointer)
            (throw (ex-info "open failed" {:code code}))))))

The symbol after the return type names the raw binding. Only the wrapper
body can use this name. The forms after the raw name are a normal fn tail.
The wrapper can have multiple arities. Its argument lists can differ from
the C function. The raw name does not enter the namespace. The wrapper
form needs a literal argtypes vector. Only the plain form accepts an
argtypes expression.
cljs
(defcfn name & args)

Defines name as a C function binding created by cfn:

(defcfn sqlite3-open "sqlite3_open" [:string :pointer] :int)

(defcfn sqlite3-open
  "Opens the database at path, storing the handle in out-param pp."
  "sqlite3_open" [:string :pointer] :int)

An optional docstring and attribute map can precede the C symbol. The final three arguments are the C symbol, argument types, and return type. defcfn preserves all metadata on name. This metadata includes ^:private.

The :library key in the attribute map selects a library for cfn:

(def sqlite (delay (ffi/load-library (extract-bundled-library!))))
(defcfn sqlite3-open {:library sqlite} "sqlite3_open"
  [:string :pointer] :int)

The value can be a library map or a function that returns one. It can also be an IDeref object that holds a library map.

Without :library, a binding searches all loaded libraries. Then it searches the default system lookup. A system library with the same name can supply the symbol.

The wrapper form binds the raw C function to a local name and defines name as the wrapper:

(defcfn open-db
  "sqlite3_open_v2" [:string :pointer :int :string] :int
  open-native
  [filename flags]
  (ffi/with-open [arena (ffi/confined-arena)]
    (let [pdb (ffi/alloc arena :pointer)
          code (open-native filename pdb flags nil)]
      (if (zero? code)
        (ffi/read pdb :pointer)
        (throw (ex-info "open failed" {:code code}))))))

The symbol after the return type names the raw binding. Only the wrapper body can use this name. The forms after the raw name are a normal fn tail. The wrapper can have multiple arities. Its argument lists can differ from the C function. The raw name does not enter the namespace. The wrapper form needs a literal argtypes vector. Only the plain form accepts an argtypes expression.

Defines name as a C function binding created by cfn:

    (defcfn sqlite3-open "sqlite3_open" [:string :pointer] :int)

    (defcfn sqlite3-open
      "Opens the database at path, storing the handle in out-param pp."
      "sqlite3_open" [:string :pointer] :int)

An optional docstring and attribute map can precede the C symbol. The final
three arguments are the C symbol, argument types, and return type. defcfn
preserves all metadata on name. This metadata includes ^:private.

The :library key in the attribute map selects a library for cfn:

    (def sqlite (delay (ffi/load-library (extract-bundled-library!))))
    (defcfn sqlite3-open {:library sqlite} "sqlite3_open"
      [:string :pointer] :int)

The value can be a library map or a function that returns one. It can also
be an IDeref object that holds a library map.

Without :library, a binding searches all loaded libraries. Then it searches
the default system lookup. A system library with the same name can supply
the symbol.

The wrapper form binds the raw C function to a local name and defines name
as the wrapper:

    (defcfn open-db
      "sqlite3_open_v2" [:string :pointer :int :string] :int
      open-native
      [filename flags]
      (ffi/with-open [arena (ffi/confined-arena)]
        (let [pdb (ffi/alloc arena :pointer)
              code (open-native filename pdb flags nil)]
          (if (zero? code)
            (ffi/read pdb :pointer)
            (throw (ex-info "open failed" {:code code}))))))

The symbol after the return type names the raw binding. Only the wrapper
body can use this name. The forms after the raw name are a normal fn tail.
The wrapper can have multiple arities. Its argument lists can differ from
the C function. The raw name does not enter the namespace. The wrapper
form needs a literal argtypes vector. Only the plain form accepts an
argtypes expression.
source (clj)source (cljs)raw docstring

find-symbolclj/s

(find-symbol sym)
(find-symbol lib sym)

Finds sym and returns a pointer to it. Returns nil for an unknown symbol.

A library value limits the search to one library and its dependencies. Without a library value, find-symbol searches all loaded libraries. Then it searches the default system lookup.

Finds sym and returns a pointer to it. Returns nil for an unknown symbol.

A library value limits the search to one library and its dependencies.
Without a library value, find-symbol searches all loaded libraries. Then it
searches the default system lookup.
source (clj)source (cljs)raw docstring

global-arenaclj/s

(global-arena)

Returns the global arena. Its memory exists until the process stops. You cannot close this arena.

Returns the global arena. Its memory exists until the process stops.
You cannot close this arena.
source (clj)source (cljs)raw docstring

load-libraryclj/s≠

(load-library lib)
clj

Loads a shared library and adds it to the symbol search.

Use load-system-library for file names that follow platform conventions.

lib can be a path, a vector of candidates, or a map of operating systems to candidates. The function tries vector entries in order. An operating-system map uses the keys :mac, :linux, and :windows:

(ffi/load-library
  {:mac ["/opt/homebrew/opt/openssl@3/lib/libcrypto.3.dylib"
         "/usr/local/opt/openssl@3/lib/libcrypto.3.dylib"]
   :linux "libcrypto.so.3"})

:darwin is an alias for :mac. For a bare name, the function also searches common installation directories. Returns a library map whose :path value identifies the loaded candidate. The map can be the first argument to cfn. In that form, cfn searches this library and its dependencies.

Loads a shared library and adds it to the symbol search.

Use load-system-library for file names that follow platform conventions.

lib can be a path, a vector of candidates, or a map of operating systems to
candidates. The function tries vector entries in order. An operating-system
map uses the keys :mac, :linux, and :windows:

    (ffi/load-library
      {:mac ["/opt/homebrew/opt/openssl@3/lib/libcrypto.3.dylib"
             "/usr/local/opt/openssl@3/lib/libcrypto.3.dylib"]
       :linux "libcrypto.so.3"})

:darwin is an alias for :mac. For a bare name, the function also searches
common installation directories. Returns a library map whose :path value
identifies the loaded candidate. The map can be the first argument to cfn.
In that form, cfn searches this library and its dependencies.
cljs

Loads a shared library and adds it to the symbol search.

Use load-system-library for file names that follow platform conventions.

lib can be a path, a vector of candidates, or a map of operating systems to candidates. The function tries vector entries in order. An operating-system map uses the keys :mac, :linux, and :windows:

(ffi/load-library
  {:mac ["/opt/homebrew/opt/openssl@3/lib/libcrypto.3.dylib"
         "/usr/local/opt/openssl@3/lib/libcrypto.3.dylib"]
   :linux "libcrypto.so.3"})

:darwin is an alias for :mac. For a bare name, the function also searches common installation directories. Returns a library map whose :path value identifies the loaded candidate. The map can be the first argument to cfn. In that form, cfn searches only this library.

Loads a shared library and adds it to the symbol search.

Use load-system-library for file names that follow platform conventions.

lib can be a path, a vector of candidates, or a map of operating systems to
candidates. The function tries vector entries in order. An operating-system
map uses the keys :mac, :linux, and :windows:

    (ffi/load-library
      {:mac ["/opt/homebrew/opt/openssl@3/lib/libcrypto.3.dylib"
             "/usr/local/opt/openssl@3/lib/libcrypto.3.dylib"]
       :linux "libcrypto.so.3"})

:darwin is an alias for :mac. For a bare name, the function also searches
common installation directories. Returns a library map whose :path value
identifies the loaded candidate. The map can be the first argument to cfn.
In that form, cfn searches only this library.
source (clj)source (cljs)raw docstring

load-system-libraryclj/s

(load-system-library name)

Loads a shared library by its short name. For example, "z" selects libz.dylib, libz.so, or z.dll. On Linux, the search also includes versioned names such as libz.so.1. Returns the same library map as load-library.

Loads a shared library by its short name. For example, "z" selects
libz.dylib, libz.so, or z.dll. On Linux, the search also includes versioned
names such as libz.so.1. Returns the same library map as load-library.
source (clj)source (cljs)raw docstring

nullclj/s

The NULL pointer.

The NULL pointer.
source (clj)source (cljs)raw docstring

null?clj/s

(null? p)

Returns true for a NULL pointer. Returns false for all other pointers.

Returns true for a NULL pointer. Returns false for all other pointers.
source (clj)source (cljs)raw docstring

placeclj/s

(place t)
(place t path)

Returns a place for read and write in layout t. path is a member name or a vector of member names and array indices. Without a path, returns a place for the whole layout.

(def parent (place bone :parent))
(read p parent)                          ;=> 7
(write p parent 3)
(read p (place outer [:msgs 1 :data :result]))
(read p (place point))

Uses the member's type for reads and writes: a struct as a map, an array as a vector, a union as a pointer on read and a pair on write. A path to a union member accepts the member's value directly on write.

Throws for an invalid path. Create a place once and reuse it.

Returns a place for read and write in layout t. path is a member name
or a vector of member names and array indices. Without a path, returns
a place for the whole layout.

    (def parent (place bone :parent))
    (read p parent)                          ;=> 7
    (write p parent 3)
    (read p (place outer [:msgs 1 :data :result]))
    (read p (place point))

Uses the member's type for reads and writes: a struct as a map, an array
as a vector, a union as a pointer on read and a pair on write. A path to
a union member accepts the member's value directly on write.

Throws for an invalid path. Create a place once and reuse it.
source (clj)source (cljs)raw docstring

pointer?clj/s≠

(pointer? x)
clj

Returns true when x is a pointer: a MemorySegment of native memory.

Returns true when x is a pointer: a MemorySegment of native memory.
cljs

Returns true when x is a pointer whose arena is open.

Returns true when x is a pointer whose arena is open.
source (clj)source (cljs)raw docstring

ptr->stringclj/s

(ptr->string p)
(ptr->string p limit)

Returns the NUL-terminated UTF-8 string at p. Returns nil for a NULL pointer.

A pointer returned by C has no size, so the read runs to the first NUL byte. This is what a :string return type does.

limit is a maximum byte count. If p has a nonzero size, the read is also bounded by that size. Throws if no NUL byte occurs within these bounds.

CAUTION: Without a limit, ptr->string can read past a buffer that has no NUL byte. This can stop the process.

Returns the NUL-terminated UTF-8 string at p. Returns nil for a NULL
pointer.

A pointer returned by C has no size, so the read runs to the first NUL
byte. This is what a :string return type does.

limit is a maximum byte count. If p has a nonzero size, the read is also
bounded by that size. Throws if no NUL byte occurs within these bounds.

CAUTION: Without a limit, ptr->string can read past a buffer that has no
NUL byte. This can stop the process.
source (clj)source (cljs)raw docstring

readclj/s≠

(read p t)
(read p t offset)
clj

Reads a value of type t from p. The default byte offset is zero.

t is a type keyword, a layout, or a place returned by place. A place specifies the layout member's type and offset.

Checks the access against the size of p. Rejects a zero-size pointer. reinterpret specifies a valid size.

Reads a value of type t from p. The default byte offset is zero.

t is a type keyword, a layout, or a place returned by place. A place
specifies the layout member's type and offset.

Checks the access against the size of p. Rejects a zero-size pointer.
reinterpret specifies a valid size.
cljs

Reads a value of type t from p. The default byte offset is zero.

t is a type keyword, a layout, or a place from place. A place is a member of a layout resolved once, so reading through it does no lookup.

Checks the access against the size of p. Rejects a zero-size pointer. reinterpret specifies a valid size.

Reads a value of type t from p. The default byte offset is zero.

t is a type keyword, a layout, or a place from `place`. A place is a
member of a layout resolved once, so reading through it does no lookup.

Checks the access against the size of p. Rejects a zero-size pointer.
reinterpret specifies a valid size.
source (clj)source (cljs)raw docstring

read-arrayclj/s≠

(read-array p t n)
(read-array p t n offset)
clj

Copies n elements of type t from pointer p, at byte offset (default 0), into a new Java array. Returns the array.

Copies raw bytes without converting elements. For example, :int, :uint and :int32 return an int[] with the same bits, so a :uint above Integer/MAX_VALUE reads as a negative int. :long and the other eight-byte types fill a long[], and :pointer fills a long[] of addresses. :byte, :char, :int8, :uint8 and :bool fill a byte[]. For pointers, use read with [:array :pointer n].

For an array of structs, or for elements decoded the way read decodes them, use read with an [:array t n] layout.

Copies n elements of type t from pointer p, at byte offset (default 0),
into a new Java array. Returns the array.

Copies raw bytes without converting elements. For example,
:int, :uint and :int32 return an int[] with the same bits, so a
:uint above Integer/MAX_VALUE reads as a negative int. :long and the other
eight-byte types fill a long[], and :pointer fills a long[] of addresses.
:byte, :char, :int8, :uint8 and :bool fill a byte[]. For pointers, use
read with [:array :pointer n].

For an array of structs, or for elements decoded the way read decodes
them, use read with an [:array t n] layout.
cljs

Copies n elements of type t from pointer p, at byte offset (default 0), into a new typed array. Returns the array.

The copy uses memcpy. The type gives the element width and nothing else: :int, :uint and :int32 fill an Int32Array with the bits as they are. :long and the other eight-byte types fill a BigInt64Array, and :pointer fills a BigInt64Array of addresses. :byte, :char, :int8, :uint8 and :bool fill an Int8Array.

For an array of structs, or for elements decoded the way read decodes them, use read with an [:array t n] layout.

Copies n elements of type t from pointer p, at byte offset (default 0),
into a new typed array. Returns the array.

The copy uses memcpy. The type gives the element width and nothing else:
:int, :uint and :int32 fill an Int32Array with the bits as they are. :long
and the other eight-byte types fill a BigInt64Array, and :pointer fills a
BigInt64Array of addresses. :byte, :char, :int8, :uint8 and :bool fill an
Int8Array.

For an array of structs, or for elements decoded the way read decodes
them, use read with an [:array t n] layout.
source (clj)source (cljs)raw docstring

reinterpretclj/s≠

(reinterpret seg size)
(reinterpret seg size arena)
(reinterpret seg size arena cleanup)
clj

Returns a view of segment seg with byte size size.

Without an arena, the view retains seg's lifetime.

With an arena, the view is valid only while that arena is open. A read after the arena closes throws. The arena calls the optional cleanup function with the view when it closes. Use this function for a C library deallocator.

CAUTION: Give the actual size. The runtime cannot know if this size is correct. A larger size permits out-of-bounds reads.

CAUTION: If the arena is closed, do not pass the view to C. C can access the released memory.

Returns a view of segment seg with byte size size.

Without an arena, the view retains seg's lifetime.

With an arena, the view is valid only while that arena is open. A read after
the arena closes throws. The arena calls the optional cleanup function with
the view when it closes. Use this function for a C library deallocator.

CAUTION: Give the actual size. The runtime cannot know if this size is
correct. A larger size permits out-of-bounds reads.

CAUTION: If the arena is closed, do not pass the view to C. C can access the
released memory.
cljs

Returns a view of pointer seg with byte size size.

Without an arena, the view retains seg's lifetime.

With an arena, the view is valid only while that arena is open. A read after the arena closes throws. The arena calls the optional cleanup function with the view when it closes. Use this function for a C library deallocator.

CAUTION: Give the actual size. The runtime cannot know if this size is correct. A larger size permits out-of-bounds reads.

CAUTION: If the arena is closed, do not pass the view to C. C can access the released memory.

Returns a view of pointer seg with byte size size.

Without an arena, the view retains seg's lifetime.

With an arena, the view is valid only while that arena is open. A read after
the arena closes throws. The arena calls the optional cleanup function with
the view when it closes. Use this function for a C library deallocator.

CAUTION: Give the actual size. The runtime cannot know if this size is
correct. A larger size permits out-of-bounds reads.

CAUTION: If the arena is closed, do not pass the view to C. C can access the
released memory.
source (clj)source (cljs)raw docstring

segmentclj/s

(segment addr)
(segment addr size)

Returns a pointer to addr. The default size is zero. A specified nonzero size enables bounds checks.

CAUTION: Keep addr before size. A transposed call can stop the process at the first read.

Returns a pointer to addr. The default size is zero.
A specified nonzero size enables bounds checks.

CAUTION: Keep addr before size. A transposed call can stop the process at
the first read.
source (clj)source (cljs)raw docstring

shared-arenaclj/s≠

(shared-arena)
clj

Returns an arena for multiple threads. Create this arena in with-open to release its memory.

Returns an arena for multiple threads.
Create this arena in with-open to release its memory.
cljs

Returns an arena. On Node.js, behaves like confined-arena. Create this arena in ffi/with-open to release its memory.

Returns an arena. On Node.js, behaves like confined-arena.
Create this arena in ffi/with-open to release its memory.
source (clj)source (cljs)raw docstring

sizeclj/s

(size p)

Returns the size of pointer p in bytes. A pointer that C returned has size 0.

Returns the size of pointer p in bytes. A pointer that C returned has
size 0.
source (clj)source (cljs)raw docstring

sizeofclj/s

(sizeof t)

Returns the size of a type keyword or struct layout, in bytes. The size of a struct includes padding.

Returns the size of a type keyword or struct layout, in bytes. The size
of a struct includes padding.
source (clj)source (cljs)raw docstring

sliceclj/s

(slice seg offset)
(slice seg offset len)

Returns a slice of seg at byte offset. By default, the slice ends with seg. len is an integer byte count, a type keyword, or a layout. To select one struct from an array:

(slice arr (* i (sizeof point)) point)

CAUTION: Keep offset before len. A transposed call throws only if the result does not fit in seg.

Returns a slice of seg at byte offset. By default, the slice ends with seg.
len is an integer byte count, a type keyword, or a layout. To select one
struct from an array:

    (slice arr (* i (sizeof point)) point)

CAUTION: Keep offset before len. A transposed call throws only if the result
does not fit in seg.
source (clj)source (cljs)raw docstring

string->ptrclj/s

(string->ptr arena s)

Copies s into arena as a NUL-terminated UTF-8 string and returns its pointer. The arena controls the lifetime of the string.

Copies s into arena as a NUL-terminated UTF-8 string and returns its
pointer. The arena controls the lifetime of the string.
source (clj)source (cljs)raw docstring

with-openclj/smacro

(with-open bindings & body)

Evaluates body with each name bound to its value. Calls .close on each value in reverse order when body returns or throws.

CAUTION: On Node.js the arena closes when body returns. Do not return a promise that still uses it.

Evaluates body with each name bound to its value. Calls .close on each
value in reverse order when body returns or throws.

CAUTION: On Node.js the arena closes when body returns. Do not return a
promise that still uses it.
source (clj)source (cljs)raw docstring

writeclj/s≠

(write p t v)
(write p t v offset)
clj

Writes v as type t to p. The default byte offset is zero. Returns nil.

t is a type keyword, a layout, or a place returned by place. When a place selects a union member, pass the member's value directly.

Checks the access against the size of p. Rejects a zero-size pointer. reinterpret specifies a valid size.

Writes v as type t to p. The default byte offset is zero. Returns nil.

t is a type keyword, a layout, or a place returned by place. When a place
selects a union member, pass the member's value directly.

Checks the access against the size of p. Rejects a zero-size pointer.
reinterpret specifies a valid size.
cljs

Writes v as type t to p. The default byte offset is zero. Returns nil.

t is a type keyword, a layout, or a place from place. Through a place the member's type is known, so a union member needs no pair.

Checks the access against the size of p. Rejects a zero-size pointer. reinterpret specifies a valid size.

Writes v as type t to p. The default byte offset is zero. Returns nil.

t is a type keyword, a layout, or a place from `place`. Through a place
the member's type is known, so a union member needs no pair.

Checks the access against the size of p. Rejects a zero-size pointer.
reinterpret specifies a valid size.
source (clj)source (cljs)raw docstring

write-arrayclj/s≠

(write-array p t arr)
(write-array p t arr offset)
clj

Copies Java array arr into memory at pointer p, at byte offset (default 0), as elements of type t. Returns nil.

Copies raw bytes without converting elements. arr must be a Java array of the matching type: an int[] for :int, a long[] for :long or :pointer, a byte[] for :char.

Copies Java array arr into memory at pointer p, at byte offset (default
0), as elements of type t. Returns nil.

Copies raw bytes without converting elements. arr must be a Java array
of the matching type: an int[] for :int, a long[] for :long or :pointer, a
byte[] for :char.
cljs

Copies typed array arr into memory at pointer p, at byte offset (default 0), as elements of type t. Returns nil.

The copy is a memcpy, as in read-array, and the array must be the typed array for the type: an Int32Array for :int, a BigInt64Array for :long or :pointer, an Int8Array for :char.

Copies typed array arr into memory at pointer p, at byte offset (default
0), as elements of type t. Returns nil.

The copy is a memcpy, as in read-array, and the array must be the typed
array for the type: an Int32Array for :int, a BigInt64Array for :long or
:pointer, an Int8Array for :char.
source (clj)source (cljs)raw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close