Skip to content
CryoCryo home
StdlibSystem

ffi

The C ABI boundary. This is the only place in the standard library where raw platform types are allowed — every other module works in length-typed Str and String.

public module ffi::libc;
public module ffi::openssl;
FileWhat it holdsImport
libcPOSIX / glibc bindings, typed enums for closed-set arguments, the flag and errno constantsimport std::ffi::libc;
opensslThe OpenSSL 3.x subset net::tls drivesimport std::ffi::openssl;

Strings across the boundary

Cryo strings carry a length and no terminator; C strings carry a terminator and no length. Translation happens at the boundary, and there is no CString wrapper type — String does the job.

Going out, build a NUL-terminated copy and pass its pointer:

import std::ffi::libc;
import std::collections::string;

mut path: String = String::with_null(name);
const fd: i32 = libc::open(path.as_ptr() as string, libc::O_RDONLY, 0);

String::with_null(source) produces an owned copy that keeps a trailing NUL. as_cstr(mut &this) does the same in place on a string you already have: it writes the terminator at index length, reserving a spare byte if needed, without changing the logical length. It is idempotent and allocation-free once that byte exists.

Coming back, restore the length:

const view: Str = Str::from(c_string);     // length via strlen; the NUL is excluded

Check pointers for null before you do it.