C FFI (Foreign Function Interface)¶
XIOM has zero-cost C interoperability. C functions and types are declared in extern blocks. The compiler generates no wrapper code. C ABI calling conventions are used directly.
unsafe is required because the compiler cannot verify C memory safety.
Extern Blocks¶
extern "C" {
fn malloc(size: UInt) -> *UInt8
fn free(ptr: *UInt8)
fn strlen(s: *UInt8) -> UInt
fn printf(format: *UInt8, ...) -> Int32
}
Calling C Functions¶
fn c_string_length(ptr: *UInt8) -> UInt {
unsafe { return strlen(ptr); }
}
fn allocate_buffer(size: UInt) -> *UInt8 {
unsafe { return malloc(size); }
}
Raw Pointers¶
Raw pointers (*T) are only usable inside unsafe blocks. They cannot be dereferenced in safe code.
unsafe {
let raw: *Int = some_c_function();
let value = *raw; // dereference -- programmer guarantees validity
*raw = 42; // write through pointer
}
Safe Wrappers¶
The recommended pattern is to wrap C libraries with safe XIOM interfaces that add contracts:
fn safe_alloc(size: UInt) -> Option[*UInt8]
requires: size > 0
{
unsafe {
let ptr = malloc(size);
if ptr == null_ptr() {
return None;
}
return Some(ptr);
}
}
fn safe_free(ptr: *UInt8) {
unsafe { free(ptr) }
}
Type Mapping¶
| C Type | XIOM Type |
|---|---|
int |
Int32 |
unsigned int |
UInt32 |
long |
Int64 |
size_t |
UInt |
char |
Int8 |
char* |
*UInt8 |
void* |
*UInt8 |
float |
Float32 |
double |
Float64 |
C-ABI Export¶
XIOM functions can be exported with C ABI for consumption from other languages:
extern "C" fn xiom_add(a: Int32, b: Int32) -> Int32 {
return a + b;
}
This compiles to a standard C-callable symbol that can be linked from Rust, Python, or any language with C FFI.
Strategy¶
XIOM does not rewrite C libraries. It wraps them with safe interfaces and contract-verified preconditions:
| Library | C LOC | XIOM Wrapper LOC |
|---|---|---|
| SQLite | 150,000 | ~200 |
| OpenSSL | 500,000 | ~300 |
| BLAS | 100,000+ | ~150 |
The C library provides battle-tested implementation. The XIOM wrapper adds contracts and type safety.
FFI Best Practices¶
- Always use
unsafeblocks -- never call C functions outsideunsafe { }. - Wrap with safe functions -- expose a safe XIOM interface with contracts.
- Validate at the boundary -- check pointer validity, buffer sizes, and nullability.
- Auto-infer contracts from C headers -- planned Phase 3 feature for mechanical binding generation.