| (1-5) | ||
|---|---|---|
| x3 | ___ | |
| x2 | ___ | |
| x1.5 | ___ | |
| x1.5 | ___ | |
| Rust | x1 | ___ |
| 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% |
| bug | 70-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
| c2rust | C → unsafe Rust |
| bindgen | C → Rust FFI |
| cbindgen | Rust → CC ABI |
| cargo-asm | Rust |
| miri | Rust 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