(1-5)
x3___
x2___
x1.5___
x1.5___
Rustx1___
x1___

≥35 → / 25-34 → / 15-24 → FFI / <15 → C

C

  • seL4
  • HPC+C

  • CVE
  • /

1FFI

CAPI

pub struct FooHandle { inner: *mut ffi::foo_handle_t }
impl FooHandle {
 pub fn open(path: &str) -> Result<Self, FooError> {
 let c_path = CString::new(path).map_err(|_| FooError::InvalidPath)?;
 let handle = unsafe { ffi::foo_open(c_path.as_ptr()) };
 if handle.is_null() { return Err(FooError::OpenFailed); }
 Ok(FooHandle { inner: handle })
 }
}
impl Drop for FooHandle { fn drop(&mut self) { unsafe { ffi::foo_close(self.inner); } } }

CunsafeFFI

2

C ABIRust>10000

trait Decompressor {
 fn decompress(&mut self, input: &[u8], output: &mut Vec<u8>) -> Result<usize, DecompressError>;
}
struct RustDecompressor { /* ... */ }
impl Decompressor for RustDecompressor { /* ... */ }
struct CDecompressor { /* ... */ }
impl Decompressor for CDecompressor { /* unsafe FFIC */ }
enum Backend { Rust(RustDecompressor), C(CDecompressor) }

3

<5000

4RustC

CcbindgenC ABICRustLinux

// Rust cbindgen  C ABI
#[no_mangle]
pub extern "C" fn new_feature_init() -> *mut c_void {
 let state = Box::new(NewFeatureState::new());
 Box::into_raw(state) as *mut c_void
}

4.1

C
  → 
   → 32
   → 4Rust
  → C
  / → 1FFI
   → 1  4

2-6
1C ≈ 0.8-1.5Rust
20-40%
30-50%

bug70-90%
30-50%
40-60%
95%+

ROI

  • <20003-6
  • 2000-100006-18
  • 10000

librsvgSVG~100000C → Rust2016-2019

SVG/CSSAPICVE

fish shell~80000C++ → Rust2020-2023

RustCXXCMakeCMake+cargo

uutils/coreutilsGNU coreutils → Rust2013

GNULinux/macOS/Windows

Rust for Linux2020

4RustCRustBinderLinux 6.1#[no_std]+allocator

c2rustC → unsafe Rust
bindgenC → Rust FFI
cbindgenRust → CC ABI
cargo-asmRust
miriRust MIRUB
loom
bindgen wrapper.h -o src/bindings.rs # FFI
c2rust transpile compile_commands.json # 
cargo clippy -- -W clippy::all # 
cargo miri test # unsafeUB
cargo build --release # 

releaseIO

debugRust debugclone

let mut result = Vec::with_capacity(estimated_size); // 
result.extend_from_slice(&source[..len]); // 
dest[..n].copy_from_slice(&src[..n]); // 
data.par_iter_mut().for_each(|x| *x = process(*x)); // rayon

  • → 5%

  • → COracle

  • bug → sanitizermiri

  • → Rustrust-toolchain.toml

  • Rust → FFICunsafe

  • → Cfuzz

  • → feature flagC/Rust

1: (1-2) → The Book + Rustlings + 
2: (2-3) → <300C + 
3: (3-4) →  +  + 
4:  → Rust + C