You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

#![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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 04:45:05