Как правильно сделать FFI для Box?

Привет

Я сделал простой парсер арифметических выражений https://github.com/anton-okolelov/simple-rust-ariphmetic-parser

Во-первых, большая просьба посмотреть код на предмет того, насколько он идеоматично написан с точки зрения Раста. Если не затруднит.

И вопрос еще есть.

для тренировки я бы хотел сделать функцию “parse” С-совместимой, чтобы использовать ее в скриптовых языках.

Функция возвращает результат типа Expression

pub enum Expression {
    Add(Box<Expression>, Box<Expression>),
    Subtract(Box<Expression>, Box<Expression>),
    Multiply(Box<Expression>, Box<Expression>),
    Divide(Box<Expression>, Box<Expression>),
    UnaryMinus(Box<Expression>),
    Value(i64),
}

Поигрался с cbindgen, енумы он подхватывает автоматом, но не знаю, как действовать в случае с Box. Надо копировать этот результат функции в сишную структуру с голыми указателями?

Си понимает только указатели, так что надо преобразовывать их через Box::into_raw(boxed_value).

1 лайк

Сделал конвертацию в сишные структуры. Посмотрите плиз кто-нибудь

И еще вопрос, кто должен очищать эту память и как? )) . После вызова функции

Для очистки памяти код на C должен вызывать обёртку на Rust, которая будет восстанавливать из указателей и освобождать все ExpressionFfi (и которую нужно написать).

В зависимости от того, для чего это выражение передаётся обратно в Си, такое дерево узлов может быть более или менее удобной структурой. Например, если код на Си должен уметь только вычислять значение выражения, то структура самого выражения может быть вообще чёрным ящиком (и содержать, например, стековый байт-код).

Спасибо за разъяснение! Примерно так?

В этом видео есть вариант, как Box в Rust превращают в std::unique_ptr в C++

1 лайк

Накидал статью

2 лайка