现有项目由 rust 实现,现在希望将部分功能封装为 C 动态库,给其他语言使用。C 库 API 使用流程是这样的:
// 不透明指针,需要使用方持有
#define Ctx void *;
// 第 1 步 初始化 Ctx,然后将指针传给使用方
int32_t ctx_open(Ctx *ctx);
// 第 2 步 调用相关功能接口时,需要将 ctx 传
int32_t ctx_use(Ctx ctx);
// 第 3 步 使用方用该方法来完成资源释放
int32_t ctx_close(Ctx ctx);
对 rust unsafe 部分不熟悉,在裸指针转换以及 Ctx 生命周期维护上卡住了。
我现在的代码大概是这样的
pub type Ptr = *mut ffi::c_void;
#[no_mangle]
pub extern "C" fn ctx_open(handle: *mut Ptr) -> i32 {
let ctx: Box<Ctx> = Box::new(Ctx { });
let ptr = Box::<Ctx>::into_raw(ctx);
let ptr = ptr as Ptr;
unsafe {*handle = ptr};
0
// 我希望 ctx 不会因为离开作用域而自动 drop,我不确定以上代码是否正确
}
#[no_mangle]
pub extern "C" fn ctx_use(handle: Ptr) -> i32 {
// 这应该需要将 handle 转换为 Ctx 可可变借用(如果不是借用,可能会导致 Ctx 对象在这个函数结束就释放了),不知道怎么做
}
#[no_mangle]
pub extern "C" fn ctx_close<'a>(handle: Ptr)-> i32 {
let mut ctx = unsafe { Box::<Ctx>::from_raw(handle as *mut Ctx)};
unsafe {drop(yy)};
0
// 释放掉资源,不知道是否正确
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.