掌握Rust调用C函数、导出Rust函数给C、以及bindgen/cbindgen工具。
use std::os::raw::c_int;
// 声明外部C函数
extern "C" {
fn abs(input: c_int) -> c_int;
}
fn main() {
let x: i32 = -42;
unsafe {
println!("abs({}) = {}", x, abs(x));
}
}
✅ 编译验证通过
// no_mangle防止名称修饰
// extern "C"使用C调用约定
#[no_mangle]
pub extern "C" fn rust_add(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
println!("rust_add(3, 4) = {}", rust_add(3, 4));
}
✅ 编译验证通过
| C类型 | Rust类型 |
|---|---|
int | c_int |
long | c_long |
char* | *mut c_char |
void* | *mut c_void |
size_t | usize |
uint8_t | u8 |
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
fn main() {
// Rust → C
let rust_str = "Hello from Rust";
let c_str = CString::new(rust_str).unwrap();
let c_ptr: *const c_char = c_str.as_ptr();
// C → Rust
unsafe {
let rust_str2 = CStr::from_ptr(c_ptr)
.to_str().unwrap();
println!("从C字符串: {}", rust_str2);
}
}
✅ 编译验证通过
// Cargo.toml
[build-dependencies]
bindgen = "0.70"
// build.rs
use std::env;
use std::path::PathBuf;
fn main() {
let bindings = bindgen::Builder::default()
.header("wrapper.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.expect("无法生成绑定");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings.write_to_file(out_path.join("bindings.rs"))
.expect("无法写入绑定");
}
用libc crate调用getpid和getenv。
实现Rust函数接受C函数指针作为回调。
定义C和Rust共享的FFI结构体。
掌握FFI——连接Rust与C的桥梁
系统编程的核心挑战是在不牺牲安全的前提下获得最大性能。Rust如何实现这个目标:
所有权系统在编译期确定每个值的生命周期,不需要运行时垃圾回收。这意味着:无停顿、可预测延迟、更少内存占用。
泛型单态化、内联、LLVM优化——高级代码编译为与手写C相当的机器码。
Send/Sync trait在编译期保证:如果是并发访问,要么只读,要么互斥。数据竞争不可能发生。
| 特性 | Rust | C | C++ |
|---|---|---|---|
| 内存安全 | ✅ 编译期 | ❌ 手动 | ⚠️ 部分RAII |
| 线程安全 | ✅ 编译期 | ❌ | ❌ |
| 无GC | ✅ | ✅ | ✅ |
| 零成本抽象 | ✅ | ⚠️ 宏 | ✅ 模板 |
| 包管理 | ✅ Cargo | ❌ | ⚠️ vcpkg |
| 学习曲线 | 陡峭 | 中等 | 极陡 |
即使Rust保证内存安全和线程安全,仍需注意:
以下练习帮助你将本课知识应用到实际场景:
阅读以下代码片段,找出潜在问题并改进:
// 仔细阅读,思考有什么问题
fn process(data: Vec) -> Vec {
let mut result = Vec::new();
for i in 0..data.len() {
result.push(data[i] * 2);
}
result
}
改进建议:使用迭代器、预分配容量、考虑溢出。
用criterion基准测试对比以下实现的性能差异:
为以下场景设计Rust API:一个支持过期时间的缓存系统。考虑所有权、错误处理和泛型。
通过本课的学习,你应该掌握以下核心要点:
如果某个要点还不够清晰,回顾本课的代码示例和内存图,动手编写代码验证你的理解。
以下资源帮助你深入学习本课主题:
本课涉及的核心概念,确保你理解每一个:
| 术语 | 说明 |
|---|---|
| 所有权 | Rust内存管理的核心机制,每个值有唯一所有者 |
| 借用 | 通过引用访问数据,不获取所有权 |
| 生命周期 | 引用有效的范围,编译期分析工具 |
| trait | Rust的接口/抽象机制,类似其他语言的接口 |
| 泛型 | 参数化类型,零成本抽象 |
| 模式匹配 | 强大的数据解构和分支机制 |
| 零成本抽象 | 高层抽象不引入运行时开销 |
| fearless concurrency | 编译器保证线程安全 |
Q: Rust学习曲线真的很陡吗?
A: 前期确实需要适应所有权和借用检查器,但一旦理解了,这些概念会让你的代码更可靠。大多数人2-4周就能上手。
Q: Rust适合什么项目?
A: 系统编程、Web服务、CLI工具、嵌入式、WASM、网络服务、数据库等。基本上需要性能和安全的地方都适合。
Q: 遇到编译错误怎么办?
A: Rust编译器的错误信息非常友好!仔细阅读,通常会指出问题所在和修复建议。也可以用cargo clippy获取更多提示。