如何将f32指针转换为Rust三维固定大小切片/数组
Rust FFI:将C的f32指针转换为三维切片
[[[f32; 2]; 2]] 由于C的行优先内存布局和Rust完全匹配,我们可以直接通过指针类型转换和slice_from_raw_parts构建目标切片,全程无需拷贝数据。
实现步骤
1. 定义Rust侧目标函数
fn foo(segments: &[[[f32; 2]; 2]]) { // 示例逻辑:遍历并打印所有线段端点 for seg in segments { println!("线段:{:?}", seg); } }
2. 编写FFI绑定函数
#[no_mangle] pub extern "C" fn foo_c(data: *const f32, segment_count: usize) { // 基础空指针检查 if data.is_null() { return; } // 将f32指针强制转换为线段类型的指针 let segments_ptr = data as *const [[f32; 2]; 2]; // 基于指针和线段数量构建切片 let segments = unsafe { std::slice::from_raw_parts(segments_ptr, segment_count) }; // 调用Rust侧业务函数 foo(segments); }
3. 关键安全注意事项
- 内存有效性:必须保证C端传入的
segment_count准确,且内存区域至少包含segment_count * 4 * sizeof(f32)字节(每个线段由2个点组成,每个点2个f32),否则会触发未定义行为。 - 内存所有权:Rust侧仅借用这段内存,不负责释放,释放逻辑必须由C端自行处理。
- 对齐兼容性:
[[f32; 2]; 2]的对齐要求与f32一致(4字节),C端的f32指针天然满足对齐条件,无需额外处理。
C端调用示例
#include <stddef.h> // 声明Rust导出的函数 void foo_c(const float* data, size_t segment_count); int main() { // 按行优先顺序定义2条线段 float segment_data[] = { // 线段1:(0.0, 0.0) → (1.0, 1.0) 0.0f, 0.0f, 1.0f, 1.0f, // 线段2:(2.0, 3.0) → (4.0, 5.0) 2.0f, 3.0f, 4.0f, 5.0f }; // 计算线段数量:总f32元素数 ÷ 每个线段的f32元素数(4) size_t count = sizeof(segment_data) / sizeof(float) / 4; foo_c(segment_data, count); return 0; }
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

