如何自动重写由bindgen创建的FFI函数的签名?

时间:2019-06-27 07:47:18

标签: binding rust ffi

我正在rust-bindgen的帮助下为C库编写绑定,为此,功能签名会自动生成为bindings.rs,如下所示:

#[repr(C)]
struct A {
    //...
}

struct B {
    //...
}

extern "C" {
    pub fn foo(x: *mut A, y: *mut B);
    //...
}

我对foo的签名不满意,因为我知道x是指向常量结构的指针。此外,我想应用this idea将此签名改进为类似

extern "C" {
    pub fn foo(x: &'_ A, y: &'_ mut B);
}

但是binding.rs具有像foo这样的函数,手工重写它们是非常耗时的任务,我认为宏(或其他)应该会有所帮助。例如,可能存在一个(或多个)魔术宏rewrite!


// hide
mod ffi {
    include!("binding.rs"); // so bunch of functions: foo, bar
}

// re-exports
extern "C" {
    rewrite!(foo); // should expand to: pub fn foo(x: &'_A, y: &'_ mut B)
    rewrite!(bar);
}

我正处于这项工作的初期。我什至不知道这样的问题是否可以通过宏或其他方法解决,所以我正在寻找任何切入点。

我已经cross-posted this question进入了Rust用户论坛。

1 个答案:

答案 0 :(得分:1)

声明性宏不能完成此操作,但过程宏可能可以做到。使用proc_macro2,您可以通过在函数声明上放置重写属性来修改函数声明的令牌流,例如

extern "C" {
    #[rustify]
    pub fn foo(x: *mut A, y: *mut B);
}

您的rustify宏将*mut Typename替换为Option<&mut Typename>

我不知道如何在不将原始声明替换为mut的情况下立即更改*const借用。