Skip to content

FFI

Calling into C with extern C blocks and raw cstr / raw ptr views.

extern "C":
def abs(x: c_int) -> c_int
def main() -> i32:
unsafe:
return abs(-42)

What’s worth noticing:

  • extern "C": is a block of bodyless C ABI declarations. The block is module-private: expose the wrapped function via a safe export def if you want it reachable from other modules.
  • The call site needs an unsafe: block. The body is otherwise fully checked.
  • c_int is a nominal alias for the C-ABI int on the target.
extern "C":
def puts(buf: *const u8) -> c_int
def main() -> i32:
unsafe:
puts(raw cstr "hello from zmeu")
return 0

What’s worth noticing:

  • raw cstr "literal" produces a *const c_char view over the string literal with an implicit NUL terminator. There is no separate b"...\0" needed.
  • raw cstr also accepts a view CStr for already-borrowed C strings (e.g. coming out of CString.as_cstr()).
  • For pointer-shaped byte buffers, use raw ptr bytes (*const u8) or raw mut ptr buf (*mut u8).

unsafe: permits three things in its body:

  1. Calls to unsafe def functions.
  2. Calls to raw extern declarations.
  3. Passing raw ptr / raw cstr / raw mut ptr views to those calls.

That’s it. The body is otherwise checked like normal code: there is no general escape hatch over the type or borrow rules. See Unsafe and FFI for the full picture.