liveBook · Manning

C standard library

As explained in Code Like a Pro in Rust

libc is a Rust crate providing bindings and platform-specific definitions for the C standard library and C-compatible types.

The libc crate supplies C-compatible types and platform-specific definitions for Rust foreign function interfaces. Use it when declaring C function signatures or data structures; mismatched types can cause undefined behavior. section 2.6 section 4.8

A reliable C interop boundary follows these practices:

  • Declare external functions inside an extern "C" block and link the required native library with #[link(name = "...")]. section 2.6
  • Use libc types such as c_int, c_ulong, c_char, c_uint, and c_uchar instead of assuming equivalent Rust types have the same C representation. section 2.6 section 4.8
  • Mark mapped structs with #[repr(C)], preserve pointer fields, and keep direct C calls inside unsafe blocks. section 2.6 section 4.8
  • Prefer rust-bindgen for substantial headers; manually copy definitions, convert types, and implement interfaces only for small cases. section 2.6 section 4.8
Listing 2.8 Code for zlib utility functions
use libc::{c_int, c_ulong};

#[link(name = "z")]
extern "C" {
   fn compress(
       dest: *mut u8,
       dest_len: *mut c_ulong,
       source: *const u8,
       source_len: c_ulong,
   ) -> c_int;
   fn compressBound(source_len: c_ulong) -> c_ulong;
   fn uncompress(
       dest: *mut u8,
       dest_len: *mut c_ulong,
       source: *const u8,
       source_len: c_ulong,
   ) -> c_int;
}

Shows a compact zlib declaration using libc types, extern "C", and an explicit native-library link. section 2.6

Wrapping zlib

A Rust wrapper allocates a destination Vec, calls compress through an unsafe FFI boundary, sets the returned length, and exposes a safe zlib_compress function. The matching uncompress wrapper can then round-trip compressed bytes. section 2.6

Building a small C library

Cargo can compile src/hello_world.c through the cc build dependency in build.rs, declare the function with libc::c_char, and convert its returned pointer with CStr. Use cargo:rerun-if-changed to avoid unnecessary rebuilds. section 2.11

How Code Like a Pro in Rust covers it

How deep it goes
Explains type mapping, repr(C), unsafe calls, wrappers, bindgen, and build scripts without developing FFI internals broadly.
Examples
Uses zlib compression, gzip-file reading, and a Cargo-built Hello World C function as concrete interoperation examples.
What it assumes
Assumes Rust and Cargo familiarity while teaching the required C types, FFI declarations, unsafe boundary, and build-script workflow.
What you can do after
Build it from scratch by declaring, linking, wrapping, and testing small C interfaces from Rust.
How it connects
Connects foreign function interface, Cargo, build scripts, C structs, zlib, rust-bindgen, and the cc crate.

Also explained in

Compare how 3 books explain C standard library →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Code Like a Pro in Rust. The section links point to the parts of the book it draws on.