Как я могу автоматически переписать сигнатуру созданных bindgen функций FFI? - PullRequest
1 голос
/ 27 июня 2019

Я пишу привязку для библиотеки C с помощью rust-bindgen, для которой сигнатуры функций автоматически генерируются в bindings.rs как:

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

struct B {
    //...
}

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

Я не очень доволен этой подписью foo, потому что я знаю, что x является указателем на постоянную структуру. Более того, я хочу применить эту идею , чтобы улучшить эту подпись до чего-то вроде

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);
}

Я на очень ранней стадии этой работы. Я даже не знаю, может ли такая проблема быть решена с помощью макроса или чего-то еще, поэтому я ищу любую точку входа.

Я написал этот вопрос на форуме пользователей Rust.

1 Ответ

1 голос
/ 27 июня 2019

Декларативный макрос не может этого достичь, но процедурный макрос может это сделать.С proc_macro2 вы можете изменить поток токенов объявления функции, поместив в него свой атрибут перезаписи, например

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

И ваш макрос rustify заменит *mut Typenameс Option<&mut Typename>.

Я не знаю, как вы изменили бы заем mut без замены исходного объявления на *const.

...