Foreign Function Interface (FFI)
Part of: Reef Language Reference Last reviewed on version: 0.8.0
Extern Declarations
Declaring C Functions
extern "C" fn strlen(s: string): size_t
extern "C" proc printf(format: string)
No function body - implementation in C library.
Type Mapping
Reef → C:
int→int32_tint8→int8_tint64→int64_tuint32→uint32_tstring→const char*bool→boolfloat→doublefloat32→floatsize_t→size_tpointer→void*
Strings across the FFI boundary (since 0.8.2)
Reef strings carry a heap-block header with an O(1) logical length; raw C strings do not. The compiler bridges the gap automatically in one direction:
- C returning
stringto Reef: the result of every user-declaredextern "C" fn ...: stringcall is boundary-copied into a Reef heap string (reef_string_dup_c). Your C function may return a static buffer, a pointer intoenviron, a string literal, ormalloc'd memory — Reef takes a value snapshot at the call site. Two consequences: the returned Reef string does not change if your C code later rewrites its buffer, and each call costs one copy (keep chatty FFI onint/pointerreturns if that matters). - C filling a Reef
stringargument (agetcwd-style out-buffer): the copy cannot help you — the buffer's logical length is stale after the fill. Callstr.sync_length(buf)(orstr.set_length(buf, n)when the C side reports a length) before reading it in safe context. - Freestanding targets (
--target *-baremetal): no boundary copy is emitted; your allocator/FFI owns the header contract (seereef_baremetal.h's allocator notes).
Example
extern "C" fn strlen(s: string): size_t
proc main()
let len: size_t = strlen("Hello")
println("String length calculated")
end main
Linking: Reef automatically links with the C standard library.
Safety Considerations
- Type mismatches between Reef and C can cause crashes
- Ensure extern declarations match actual C signatures
- String lifetimes managed by Reef GC
Previous: 100_UNSAFE.md Next: 110_INLINE_ASSEMBLY.md Index: 000_INDEX.md