Rust FFI:如何向传入的C指针写入数据(类C API实现)
问题解决:Rust C兼容API中指针赋值后C端仍为NULL的问题
核心原因
你当前的代码里,Rust函数接收的*mut Engine是传值参数,函数内部修改的只是这个指针的副本,外部C代码里的qe变量根本不会被更新。要修改外部的指针变量,必须传递指针的指针(**Engine),让函数能直接写入外部变量的内存地址。
修改后的Rust代码
use std::os::raw::c_int; pub extern "C" fn create_engine(qe_ptr_ptr: *mut *mut Engine) -> c_int { // 先检查传入的指针是否为空,避免未定义行为 if qe_ptr_ptr.is_null() { return -1; // 自定义错误码表示参数非法 } match Engine::new() { Ok(engine) => { // 将Engine包装成Box并转为裸指针,然后写入外部指针变量 let engine_ptr = Box::into_raw(Box::new(engine)); unsafe { *qe_ptr_ptr = engine_ptr; } 0 // 成功返回0 } Err(e) => { eprintln!("创建Engine失败:{:#?}", e); 1 // 错误返回1 } } }
修改后的C调用代码
Engine *qe = NULL; int res = create_engine(&qe); // 传递指针的地址 if (res != 0) { throw std::runtime_error("Failed to create engine"); } // 此时qe已指向创建好的Engine实例
关键说明
- 指针的指针的作用:通过传递
&qe,Rust函数能直接访问并修改C端qe变量的内存,把新创建的Engine指针写入其中。 - 安全检查:Rust里先判断
qe_ptr_ptr是否为NULL,避免解引用空指针导致的未定义行为。 - 内存管理:用
Box::into_raw把Rust的Box转为裸指针后,后续需要在Rust的销毁API(比如destroy_engine)里用Box::from_raw回收内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Oscar Franco
相关产品推荐
相关产品推荐

