rust-ffi-interop

Implement Rust FFI bindings for Python, C, and WASM using PyO3, cbindgen, and bindgen.

Updated Mar 29, 2026
One-click install
npx skills add https://github.com/luckyegg168/rust-skill --skill rust-ffi-interop-luckyegg168
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: rust-ffi-interop
Source: https://github.com/luckyegg168/rust-skill/tree/main/rust-skills/rust-ffi-interop
Command: npx skills add https://github.com/luckyegg168/rust-skill --skill rust-ffi-interop-luckyegg168

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill requires pyo3, libc, bindgen, cbindgen, maturin, and includes references (resource) components.

What problem does it solve? Crossing language boundaries in Rust is error-prone: memory layout mismatches, panics escaping across FFI, null pointer dereferences, and ownership leaks cause crashes and undefined behavior. This Skill provides the patterns and tooling knowledge to build safe Rust ↔ C/Python/WASM interop. ## Core Features & Use Cases - PyO3 0.23 Python Bindings: Build Python modules with #[pyclass], #[pyfunction], and #[pymodule], packaged via maturin into installable wheels. - C Interop Toolchain: Generate C headers from Rust with cbindgen and Rust bindings from C headers with bindgen, using extern "C", #[repr(C)], and cdylib/staticlib crate types. - Memory & Panic Safety: Apply CString/CStr conversion rules, cross-language ownership contracts, opaque handle patterns, and catch_unwind panic boundaries. - Use Case: You have a performance-critical geometry library in Rust and want to call it from Python. Use this Skill to wrap it with PyO3, handle errors as Python exceptions, and ship it as a pip-installable wheel. ## Quick Start Use the rust-ffi-interop skill to create a PyO3 module exposing my Rust vector math functions to Python with proper error handling.

Frequently Asked Questions about rust-ffi-interop

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I call Rust code from Python using PyO3?▼

Use PyO3 with maturin: mark structs with #[pyclass], functions with #[pyfunction], and assemble them in a #[pymodule]. Set crate-type to cdylib in Cargo.toml, then run maturin develop or maturin build --release to produce an installable wheel.

What is the difference between cbindgen and bindgen?▼

cbindgen generates C header files from Rust source code, exposing Rust functions to C callers. bindgen works in the opposite direction, generating Rust FFI bindings from existing C header files so Rust can call C libraries.

Why does my Rust FFI function crash with a segfault?▼

Segfaults usually come from dereferencing null pointers or invalid C strings passed from external code. Always check ptr.is_null() at function entry and never trust pointer validity from across the FFI boundary.

Can Rust panic across an extern C function boundary?▼

No, unwinding across an FFI boundary is undefined behavior. Wrap every extern "C" entry point in std::panic::catch_unwind and return an error code instead. Note that catch_unwind cannot intercept aborts when panic = "abort" is set.

How do I safely pass strings between Rust and C?▼

Use CString::new and into_raw to transfer Rust-owned strings to C, providing a matching free function that calls CString::from_raw. For C-to-Rust, borrow with CStr::from_ptr and convert via to_str() to handle invalid UTF-8.

Why do I get undefined symbol errors when loading my Rust library?▼

The function is missing #[no_mangle] or extern "C", or the crate-type is not set to cdylib. Add #[no_mangle] pub extern "C" to exported functions and set crate-type = ["cdylib"] in Cargo.toml.