#![no_std]环境下通过FFI实现C向Rust传递数组的最优方案问询
no_std 环境下 C 向 Rust 传递可变数组的最优方案
你之前用到的 std::slice::from_raw_parts 系列接口本身不需要依赖 std 标准库,它的实际实现位于 Rust 核心库 core 中,std 仅做了一层重导出。所有 #![no_std] 环境都可以直接调用 core::slice 下的同名接口,包括嵌入式类的小众平台也完全支持。
针对可变数组的处理场景,直接使用 core::slice::from_raw_parts_mut 即可,完整流程如下:
- C 侧传递参数时必须同时传入两个值:数组的可变原始指针、数组元素的总长度
- Rust 侧接收参数后先做空指针、长度为 0 的合法性校验,避免非法内存访问
- 在 unsafe 块中调用
from_raw_parts_mut,将指针和长度转换为 Rust 原生的可变切片&mut [T],之后就可以正常对切片做读写操作
示例代码如下:
#![no_std] use core::slice; // 导出给C调用的接口 #[no_mangle] pub extern "C" fn process_c_array(ptr: *mut u8, len: usize) { // 前置合法性校验 if ptr.is_null() || len == 0 { return; } // 转换为可变切片 let mut array = unsafe { slice::from_raw_parts_mut(ptr, len) }; // 可直接对切片做任意读写操作,示例:所有元素加1 for item in array.iter_mut() { *item += 1; } }
需要严格遵守的安全约束(unsafe 调用的前提由开发者自行保证):
- 传入的指针必须对齐、非空,且指向的内存区域在切片的整个生命周期内有效,不会被C侧释放或回收
- 传入的长度必须和C侧数组的实际元素数量完全一致,避免越界访问
- 可变切片的生命周期内,对应的内存区域不能有其他并发的读写访问,避免别名冲突
如果需要传递自定义结构体的数组,需要给Rust侧的结构体添加 #[repr(C)] 标注,保证和C侧的内存布局完全一致,避免解析错误。
内容的提问来源于stack exchange,提问作者Cactus
相关产品推荐
相关产品推荐

