Использование перечисления C/C++ из .h в Rust

Проект 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. Есть ли способ сделать это? Я изучил биндген, но похоже, что он компилируется, тогда как это только заголовок.

Я бы сделал парсер с nom и друзьями и преобразовал его в перечисления ржавчины, возможно, с помощью макроса.

MeetTitan 16.08.2024 19:03

Вам нужно взаимодействовать с этим перечислением через FFI? Или вам просто нужно подобное определение в Rust?

kmdreko 16.08.2024 19:13

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

Coder909 16.08.2024 19:17

Я бы написал сценарий awk или perl, который будет использовать этот файл и выдавать все, что вам нужно.

catnip 16.08.2024 21:35

В чем проблема bindgen? Я только что попробовал это с кодом, который вы опубликовали, и он работал нормально.

Jmb 16.08.2024 21:44

Кажется, я понял, как это сделать с помощью биндгена. Мне это не показалось простым, когда я начал вникать в это.

Coder909 16.08.2024 21:46

Вам не нужно компилировать внешнюю библиотеку для использованияbindgen. Пока у вас есть файл .h, а затем вы указываете вашему ящику ссылаться на библиотеку в вашем файле build.rs, у вас все будет хорошо.

Brandon Piña 16.08.2024 21:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
98
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В итоге для этого я использовал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.

Coder909 16.08.2024 22:34

Другие вопросы по теме

Похожие вопросы

Как правильно использовать Enable_shared_from_this с io_context
Почему размер структуры меняется в зависимости от того, используется ли начальное значение?
Попытка подключить MessageBox в C++ DLL и использовать их в приложении C#
Обход ошибки GCC для создания автоматически типизированного векторного литерала указателей функций с немедленным доступом
Макрос C++ для определения перечислений и вспомогательной функции для преобразования из int в это перечисление
Почему я не могу генерировать пары чисел из std::views::iota в С++ 20
Передать std::unique_ptr в std::bind
Вызывает ли оценка короткого замыкания С++ скачки и очистку конвейера ЦП?
Как заставить функцию принимать все типы итераторов, но специализируться только на одном типе?
Инициализирует ли инициализация значения сначала нулевые значения членов объекта даже с предоставленным инициализатором элемента по умолчанию в C++?