恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

11-Rust 不安全编程(unsafe 关键字 + 裸指针 + FFI + 内联汇编 + 内存安全保证)

  • 首页
  • 资讯中心
  • /
  • 11-Rust 不安全编程(unsafe 关键字 + 裸指针 + FFI + 内联汇编 + 内存安全保证)

相关资讯

Java-ThreadLocal内存泄漏-线程池场景下的成因与正确用法 2026/9/15 8:30:20
算法 Day3-队列 / deque + 链表 2026/9/15 8:30:20
手把手教你学Simulink——基于相移控制(PSM)的双向全桥 DC‑DC(DAB)变换器回流功率(Circulating Power / Back Flow)优化仿真 2026/9/15 8:30:20

最新资讯

谐波小波滤波原理与MATLAB实现:从频域盒式窗口到特定频率提取
防水连接器的密封介绍
AI前端面试冲刺:从大模型接入到流式输出的实战指南
音视频修炼之编码器(二):x2645调参实战
传统SEO已死?多店商家如何抢占AI搜索第一屏
HarmonyOS 7 小艺智能体确认流程:确认后参数被改了,怎样防止执行另一个动作

今日推荐

GDPR下大数据架构重构与隐私保护实践
多组学数据平台架构设计与优化实践
企业主数据管理系统架构设计与实施全解析

本周热门

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化
Flutter应用改名全指南:从Android到iOS的配置与工具实践

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

11-Rust 不安全编程(unsafe 关键字 + 裸指针 + FFI + 内联汇编 + 内存安全保证)

发布时间:2026/9/15 8:30:20
11-Rust 不安全编程(unsafe 关键字 + 裸指针 + FFI + 内联汇编 + 内存安全保证) 摘要本文深入讲解 Rust 不安全编程核心知识涵盖 unsafe 关键字使用场景、裸指针操作、外部函数接口FFI、内联汇编、内存安全保证、unsafe 代码审查等核心内容。每个知识点配有完整代码示例、对比表格、实战场景及常见问题解答帮助开发者在必要时安全地使用 unsafe 代码。关键词Rust、unsafe、不安全编程、裸指针、FFI、内联汇编、内存安全、外部函数接口适合人群已掌握 Rust 基础的开发者、需要与 C 代码交互的程序员、想深入理解内存模型的开发者阅读时间约 55 分钟版本信息Rust 1.70 | 兼容 Windows/macOS/Linux 目录导航文章目录 目录导航一、unsafe 关键字1.1 unsafe 使用场景1.2 unsafe 函数1.3 unsafe trait二、裸指针操作2.1 裸指针基础2.2 指针算术2.3 从指针创建引用三、外部函数接口 FFI3.1 调用 C 代码3.2 被 C 调用3.3 字符串 FFI四、内联汇编4.1 基本语法4.2 输入输出4.3 架构特定汇编五、内存安全保证5.1 内存安全规则5.2 安全封装六、unsafe 代码审查6.1 审查清单6.2 文档化 综合实战案例实战安全封装 C 库❓ 常见问题 FAQ 学习资源与建议学习建议官方资源练习平台 参考资料一、unsafe 关键字1.1 unsafe 使用场景Rust 的 unsafe 关键字允许绕过编译器的安全检查仅在必要时使用。unsafe 允许的操作操作说明示例解引用裸指针*const T、*mut T*ptr调用 unsafe 函数标记为 unsafe 的函数unsafe { foo() }访问或修改可变静态变量static mutunsafe { STATIC_VAR 1 }实现 unsafe trait标记为 unsafe 的 traitunsafe impl Send for Foo访问 union 字段union 类型union.field1.2 unsafe 函数unsafefndangerous(){println!(This is an unsafe function);}fnmain(){// 必须在 unsafe 块中调用unsafe{dangerous();}}1.3 unsafe traitunsafetraitMyUnsafeTrait{fndo_something(self);}structMyStruct;unsafeimplMyUnsafeTraitforMyStruct{fndo_something(self){println!(Doing something unsafe);}}unsafe 使用原则原则说明示例最小化 unsafe仅在必要时使用封装 unsafe 代码文档化不变量说明安全前提/// # Safety测试边界条件验证安全性单元测试审查代码仔细审查 unsafe 块Code Review二、裸指针操作2.1 裸指针基础裸指针不进行安全检查需要手动管理。fnmain(){letmutnum5;// 创建裸指针letr1numas*consti32;letr2mutnumas*muti32;// 解引用需要 unsafeunsafe{println!(r1 is: {},*r1);println!(r2 is: {},*r2);// 修改值*r210;println!(num is now: {},num);}}裸指针类型对比类型说明可变性示例*const T不可变裸指针不可变let ptr x as *const i32*mut T可变裸指针可变let ptr mut x as *mut i322.2 指针算术fnmain(){letmutvvec![1,2,3,4,5];letptrv.as_mut_ptr();unsafe{// 指针算术letsecondptr.add(1);println!(Second element: {},*second);// 修改值*second20;println!(Vector: {:?},v);}}指针操作对比操作方法说明偏移ptr.add(offset)向前偏移偏移ptr.sub(offset)向后偏移差值ptr1.offset_from(ptr2)指针差值比较ptr1 ptr2地址比较对齐ptr.align_offset(align)对齐偏移2.3 从指针创建引用fnmain(){letmutx42;letptrmutxas*muti32;unsafe{// 从裸指针创建引用letreference:muti32mut*ptr;*reference100;}println!(x {},x);}安全注意事项注意事项说明风险空指针检查是否为 null解引用 null 导致 UB悬垂指针指向已释放内存访问无效内存数据竞争多线程访问未定义行为对齐指针必须对齐未对齐访问 UB三、外部函数接口 FFI3.1 调用 C 代码Rust 可以通过 FFI 调用 C 函数。// 声明外部 C 函数externC{fnabs(input:i32)-i32;fnprintf(format:*consti8,...)-i32;}fnmain(){unsafe{println!(Absolute value: {},abs(-5));}}3.2 被 C 调用// 导出 C 可调用的函数#[no_mangle]pubexternCfnadd(a:i32,b:i32)-i32{ab}FFI 类型映射Rust 类型C 类型说明c_charchar字符c_intint整数c_floatfloat浮点数c_doubledouble双精度c_voidvoid空指针3.3 字符串 FFIusestd::ffi::{CStr,CString};usestd::os::raw::c_char;externC{fnstrlen(s:*constc_char)-usize;}fnmain(){// Rust - C 字符串letc_stringCString::new(Hello from Rust).unwrap();unsafe{letlenstrlen(c_string.as_ptr());println!(String length: {},len);}// C - Rust 字符串letc_strCStr::from_bytes_with_nul(bHello\0).unwrap();letrust_strc_str.to_str().unwrap();println!(Rust string: {},rust_str);}字符串转换对比转换方法说明Rust - CCString::new()创建 C 字符串C - RustCStr::from_ptr()从指针创建字节转换to_bytes_with_nul()包含 null 终止符字符串转换to_str()转为 Rust str四、内联汇编4.1 基本语法Rust 1.59 支持稳定的内联汇编。fnmain(){letx:u64;unsafe{std::arch::asm!(mov {}, 5,out(reg)x,);}println!(x {},x);}4.2 输入输出fnmain(){leta:u6410;letb:u6420;letresult:u64;unsafe{std::arch::asm!(add {0}, {1},inout(reg)aresult,in(reg)b,);}println!({} {} {},a,b,result);}汇编操作数对比操作数说明示例in(reg)输入in(reg) valueout(reg)输出out(reg) valueinout(reg)输入输出inout(reg) valuelateout(reg)延迟输出lateout(reg) valueconst常量const 5sym符号sym function_name4.3 架构特定汇编#[cfg(target_arch x86_64)]fncpuid()-(u32,u32,u32,u32){leteax;letebx;letecx;letedx;unsafe{std::arch::asm!(cpuid,in(eax)0,in(ecx)0,out(eax)eax,out(ebx)ebx,out(ecx)ecx,out(edx)edx,);}(eax,ebx,ecx,edx)}五、内存安全保证5.1 内存安全规则即使使用 unsafe也必须保证内存安全。内存安全规则规则说明违反后果不悬垂指针必须指向有效内存UB不空指针解引用前检查 null崩溃不数据竞争同一时间只有一个可变引用UB对齐指针必须正确对齐UB初始化必须初始化后读取UB5.2 安全封装structMyVec{ptr:*muti32,len:usize,cap:usize,}implMyVec{fnnew()-Self{Self{ptr:std::ptr::null_mut(),len:0,cap:0,}}// 安全接口fnpush(mutself,value:i32){ifself.lenself.cap{self.grow();}unsafe{*self.ptr.add(self.len)value;}self.len1;}fngrow(mutself){// 内部 unsafe 实现// 对外提供安全接口}}封装原则原则说明示例安全接口对外提供安全 APIfn push()内部 unsafe内部使用 unsafeunsafe { *ptr value }不变量检查验证安全前提assert!(!ptr.is_null())文档化说明安全要求/// # Safety六、unsafe 代码审查6.1 审查清单检查项说明示例指针有效性指针指向有效内存!ptr.is_null()生命周期引用生命周期正确不返回悬垂引用别名规则遵守借用规则不创建多个可变引用对齐指针正确对齐ptr.align_offset()初始化内存已初始化不读取未初始化值6.2 文档化/// # Safety////// This function is unsafe because:/// - ptr must be a valid pointer/// - ptr must be properly aligned/// - ptr must point to initialized memory/// - The memory must not be accessed elsewhereunsafefnprocess_data(ptr:*muti32,len:usize){// 实现} 综合实战案例实战安全封装 C 库usestd::ffi::{CStr,CString};usestd::os::raw::c_char;// 外部 C 函数声明externC{fnstrdup(s:*constc_char)-*mutc_char;fnfree(ptr:*mutc_void);}usestd::os::raw::c_void;/// 安全封装 C 字符串pubstructSafeCString{ptr:*mutc_char,}implSafeCString{/// 从 Rust 字符串创建pubfnnew(s:str)-ResultSelf,std::ffi::NulError{letc_stringCString::new(s)?;letptrunsafe{strdup(c_string.as_ptr())};Ok(Self{ptr})}/// 转为 Rust 字符串pubfnto_str(self)-Resultstr,std::str::Utf8Error{unsafe{letc_strCStr::from_ptr(self.ptr);c_str.to_str()}}}implDropforSafeCString{fndrop(mutself){unsafe{free(self.ptras*mutc_void);}}}fnmain(){letsSafeCString::new(Hello, FFI!).unwrap();println!({},s.to_str().unwrap());}项目知识点FFI 调用 C 函数CString 转换安全封装 unsafe 代码Drop 自动释放内存❓ 常见问题 FAQQ1什么时候应该使用 unsafeA以下场景可以考虑使用 unsafe与 C 代码交互FFI实现高性能数据结构访问硬件或系统调用实现底层抽象智能指针、集合Q2unsafe 代码一定不安全吗A不是。unsafe 只是绕过编译器检查开发者必须手动保证安全。正确编写的 unsafe 代码可以是安全的。Q3如何调试 unsafe 代码A调试技巧使用 Miri 检测 UBcargo nightly miri run使用 AddressSanitizerRUSTFLAGS-Z sanitizeraddress编写单元测试验证安全性仔细审查不变量Q4FFI 字符串转换有什么注意事项A注意事项C 字符串以 null 结尾Rust 字符串可能包含 null使用CString转换 Rust - C使用CStr转换 C - Rust注意内存释放Q5如何保证 unsafe 代码的正确性A保证正确性方法编写详细的/// # Safety文档使用 Miri 检测 UB编写全面的测试Code Review 审查最小化 unsafe 范围 学习资源与建议学习建议1.尽量避免 unsafe优先使用安全抽象2.理解内存模型深入理解指针和内存布局3.使用 Miri检测未定义行为4.封装 unsafe对外提供安全接口5.文档化详细说明安全前提官方资源Rust Book - unsafe RustRustonomiconstd::arch 文档Miri 工具练习平台RustlingsExercism Rust TrackCodewars Rust 挑战 参考资料The Rust Programming LanguageThe RustonomiconRust 中文社区

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号