AtlatestRepositorysigil-ffi
1# sigil-ffi
2
3Dynamic Foreign Function Interface for [Sigil](https://codeberg.org/sigil/sigil).
4
5Call C library functions from Sigil at runtime without writing glue
6code. Built on a vendored dyncall, which provides portable calling
7conventions including struct-by-value passing on every supported arch
8(x86_64, aarch64, arm32, riscv, mips, ppc, sparc, s390, …).
9
10## Modules
12| Module | Purpose |
13|--------------|----------------------------------------------------|
14| `(sigil ffi)`| Library load, symbol lookup, call, structs, callbacks |
16## API summary
18| Procedure | Purpose |
19|------------------------------------|----------------------------------------------|
20| `c-library` | Open a shared library by name |
21| `c-library-close` | Close a previously opened library |
22| `c-symbol` | Resolve a symbol in a library |
23| `c-function` | Bind a function with arg-types and ret-type |
24| `define-c-library` | Convenience macro for binding many functions |
25| `c-sizeof` / `c-alignof` | Query size/alignment of an FFI type |
26| `make-pointer` / `pointer-address` | Build/read raw pointer values |
27| `pointer-ref` / `pointer-set!` | Dereference a pointer at a typed offset |
28| `string->pointer` / `pointer->string` | String/pointer round-trip |
29| `pointer->bytevector` / `bytevector->pointer` | Bytevector bridge |
30| `c-alloc` / `c-free` / `with-c-alloc` | Manual memory |
31| `c-errno` / `c-strerror` | errno + strerror access |
32| `c-struct-layout` / `c-struct-ref` / `c-struct-set!` | Struct field access |
33| `c-struct->dict` / `dict->c-struct` | Struct/dict marshalling |
34| `c-callback` / `c-callback-release` | Bind a Scheme procedure as a C callback |
36FFI type constants: `ffi/void`, `ffi/bool`, `ffi/int8`..`ffi/uint64`,
37`ffi/float`, `ffi/double`, `ffi/pointer`, `ffi/string`, plus
38arch-relative `ffi/int`, `ffi/uint`, `ffi/long`, `ffi/ulong`,
39`ffi/size-t`.
41## System prerequisites
43A working C toolchain. dyncall is vendored under `vendor/dyncall/` and
44compiled in-tree; no system `libdyncall` required. Your platform must
45be one dyncall supports — see `vendor/dyncall/dyncall/README*` for the
46arch matrix.
48## Dependencies
50- sigil-stdlib
52## Build
54```sh
55sigil deps install
56sigil build
57sigil test --report
58```
60The first build compiles dyncall + dyncallback (`vendor/dyncall/`)
61plus `native/ffi.c`. Subsequent builds hit the cache.
63## Usage
65```scheme
66(import (sigil ffi))
68(define libm (c-library "libm"))
69(define cbrt (c-function libm "cbrt" (list ffi/double) ffi/double))
70(cbrt 27.0) ; => 3.0
72(define libc (c-library "libc"))
73(define getenv (c-function libc "getenv" (list ffi/string) ffi/string))
74(getenv "HOME") ; => "/home/you"
75```
77`define-c-library` collapses the bind-many-functions pattern:
79```scheme
80(import (sigil ffi))
82(define-c-library libm "libm"
83 (cbrt (ffi/double) ffi/double)
84 (sqrt (ffi/double) ffi/double)
85 (pow (ffi/double ffi/double) ffi/double))
87(cbrt 27.0) ; => 3.0
88(pow 2.0 10.0) ; => 1024.0
89```
91## License
93BSD-3-Clause.
95Vendored dyncall (under `vendor/dyncall/`) is distributed under a
96permissive ISC-style license — see `vendor/dyncall/LICENSE`.
97sigil-ffi's own sources are BSD-3-Clause.