Data across the boundary¶
Level: 301 · deep dive
Stub — an outline, not a lesson. There is no runnable example behind this page yet, so nothing on it has been through the check that backs every other claim in this library. The bullets below are the questions the finished page has to answer.
One line: A call crosses the boundary for free, but data does not — every value needs a layout both sides agree on and an owner both sides agree on, and the rule that prevents most FFI memory bugs is that whoever allocated a value is the one who frees it.
What it has to cover¶
- Primitives:
c_int,c_longand friends fromcore::ffiinstead of guessing widths, andbool,charandusizeas the three that surprise people - Strings: a Rust
&strcarries a length and no terminator, a C string the reverse.CStr↗ for borrowing a C string,CStringfor lending one, thec"..."literal, and the encoding question — C's bytes are not promised to be UTF-8 - Structs:
#[repr(C)]layout, padding, and a struct C can see into against an opaque one it only holds a pointer to - Collections: a slice as a pointer and a length, and why a
Veccannot be handed over as it stands - Ownership:
Box::into_rawto give a value to C andBox::from_rawin a matching_freefunction to take it back — and why C'sfreeon Rust's allocation is undefined behaviour even when it seems to work - Borrowed data: a pointer C may keep only for the duration of a call, and how to say that in the header
- The other direction: a
char *from C'sstrdupis freed with C'sfree, neverCString::from_raw, whose docs warn that taking ownership of a string allocated by foreign code is likely undefined behaviour; andfrom_rawtwice on one pointer is a double free - API shapes that settle ownership before any code is written: the caller passes a buffer and its length, every function that returns memory has a matching
_free, or the value lives behind a handle only the library creates and destroys — and callbacks across FFI for the user-data pointer C keeps
The trap it exists for¶
Freeing across the boundary. free() on a pointer that came from a Rust Box, or dropping in Rust what C's malloc produced, mixes two allocators; on some platforms it runs for months before it corrupts the heap.
See also¶
- Calling C — "the call is free, the data is not", with
CStringverified - FFI-safe types — making the types themselves carry the rules
- A record on the wire ↗ — struct padding, measured, in the C learning library
- Six kinds of string — where
CStrandCStringsit among Rust's strings - The global allocator — whose allocation a
Boxis
Po polsku¶
Samo wywołanie przez granicę C–Rust nic nie kosztuje, ale dane już tak: każda wartość potrzebuje układu w pamięci, na który zgadzają się obie strony, i właściciela, na którego też się zgadzają. Zasada, która zapobiega większości błędów pamięci w FFI, brzmi: kto zaalokował, ten zwalnia. &str w Ruscie ma długość i nie ma terminatora, łańcuch w C — odwrotnie, dlatego istnieją CStr i CString.
Szukaj po polsku: przekazywanie danych przez FFI · łańcuchy znaków C w Ruscie · rust cstr cstring ffi · rust box into_raw from_raw ffi