V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wsa10054
V2EX  ›  Rust

练习实现 cdylib,卡住了,有没有使用类似技术开源的项目可以学习一下?

  •  
  •   wsa10054 · 2022-12-02 22:13:57 +08:00 · 1797 次点击
    这是一个创建于 759 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现有项目由 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
        // 释放掉资源,不知道是否正确
    }
    
    5 条回复    2022-12-04 13:09:10 +08:00
    bearice
        1
    bearice  
       2022-12-02 23:42:08 +08:00
    1) The into_raw function consumes a box and returns the raw pointer. It doesn’t destroy T or deallocate any memory.
    2) let ctx : &Ctx= unsafe { &*handle.cast() };
    3) 没错
    sosilver
        2
    sosilver  
       2022-12-02 23:47:28 +08:00 via Android
    rust 这边没必要用 void *,写个*mut T 还清楚些;
    怎么获得引用?当然是 dereferencing ;
    使用指针时注意判断 null
    sosilver
        3
    sosilver  
       2022-12-03 00:22:42 +08:00 via Android
    翻了下 wasmer 和 slint-ui 的 ffi ,*mut T, &mut T, Option<&mut T>, Option<Box<T>>啥都在用,也没什么检查,看来还是怎么方便怎么来🤣
    wsa10054
        4
    wsa10054  
    OP
       2022-12-03 11:59:16 +08:00
    @bearice
    @sosilver
    谢啦!
    elden
        5
    elden  
       2022-12-03 13:36:35 +08:00
    可以试试 safer_ffi ,更容易 /安全地写 FFI 胶水代码。
    cppc
        6
    cppc  
       2022-12-04 13:09:10 +08:00
    Rust FFI Omnibus 是使用 Rust 编写代码 用到 其他语言 的示例集合.

    http://llever.com/rust-ffi-omnibus/
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1232 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 17:52 · PVG 01:52 · LAX 09:52 · JFK 12:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.