Проект Cargo требует использования перечисления из большого заголовочного файла C. Существует не менее 1000 различных вариантов этого перечисления.
Вот пример того, как выглядит заголовок:
#ifndef MY_ENUMS_H
#define MY_ENUMS_H
enum Status {
OK = 0,
OUR_BASE = OK,
CONNECTION_ERROR = OUR_BASE + 1,
OPEN_FAILED = OUR_BASE + 2,
...
};
#endif // MY_ENUMS_H
Я хотел бы повторно использовать их в Rust. Есть ли способ сделать это? Я изучил биндген, но похоже, что он компилируется, тогда как это только заголовок.
Вам нужно взаимодействовать с этим перечислением через FFI? Или вам просто нужно подобное определение в Rust?
Буквально просто это нужно для аналогичного определения в Rust. Устаревший код C по-прежнему регулярно обновляется, и возможность автоматически получать его и получать новые варианты является плюсом.
Я бы написал сценарий awk
или perl
, который будет использовать этот файл и выдавать все, что вам нужно.
В чем проблема bindgen
? Я только что попробовал это с кодом, который вы опубликовали, и он работал нормально.
Кажется, я понял, как это сделать с помощью биндгена. Мне это не показалось простым, когда я начал вникать в это.
Вам не нужно компилировать внешнюю библиотеку для использованияbindgen. Пока у вас есть файл .h, а затем вы указываете вашему ящику ссылаться на библиотеку в вашем файле build.rs, у вас все будет хорошо.
В итоге для этого я использовалbingen.
файл build.rs:
fn main() {
let bindings = bindgen::builder().header("./src/include/enum.h").generate().expect("Unable to generate bindings");
bindings.write_to_file("./src/enum.rs").expect("Couldn't write bindings");
}
Пример файла src/main.rs:
include!("enum.rs");
fn main() {
let status: Status = Status_CONNECTION_ERROR;
}
Кроме того, вы также можете сделать перечисления более похожими на перечисления Rust, если добавите в построитель .default_enum_style(bindgen::EnumVariation::Rust {...}). Это не позволит выходным данным выглядеть как Status_CONNECTION_ERROR и более похоже на Status::CONNECTION_ERROR.
Я бы сделал парсер с nom и друзьями и преобразовал его в перечисления ржавчины, возможно, с помощью макроса.