AtlatestRepositorysigil-ffi
1
# sigil-ffi3
Dynamic Foreign Function Interface for [Sigil](https://codeberg.org/sigil/sigil).5
Call C library functions from Sigil at runtime without writing glue6
code. Built on a vendored dyncall, which provides portable calling7
conventions including struct-by-value passing on every supported arch8
(x86_64, aarch64, arm32, riscv, mips, ppc, sparc, s390, …).10
## Modules12
| Module | Purpose |13
|--------------|----------------------------------------------------|14
| `(sigil ffi)`| Library load, symbol lookup, call, structs, callbacks |16
## API summary18
| 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 |36
FFI type constants: `ffi/void`, `ffi/bool`, `ffi/int8`..`ffi/uint64`,37
`ffi/float`, `ffi/double`, `ffi/pointer`, `ffi/string`, plus38
arch-relative `ffi/int`, `ffi/uint`, `ffi/long`, `ffi/ulong`,39
`ffi/size-t`.41
## System prerequisites43
A working C toolchain. dyncall is vendored under `vendor/dyncall/` and44
compiled in-tree; no system `libdyncall` required. Your platform must45
be one dyncall supports — see `vendor/dyncall/dyncall/README*` for the46
arch matrix.48
## Dependencies50
- sigil-stdlib52
## Build54
```sh55
sigil deps install56
sigil build57
sigil test --report58
```60
The first build compiles dyncall + dyncallback (`vendor/dyncall/`)61
plus `native/ffi.c`. Subsequent builds hit the cache.63
## Usage65
```scheme66
(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.072
(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
```scheme80
(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.088
(pow 2.0 10.0) ; => 1024.089
```91
## License93
BSD-3-Clause.95
Vendored dyncall (under `vendor/dyncall/`) is distributed under a96
permissive ISC-style license — see `vendor/dyncall/LICENSE`.97
sigil-ffi's own sources are BSD-3-Clause.