Например,
#[crate_type="lib"];
pub struct Foo { x: i16 }
#[no_mangle]
pub extern "C" fn bar(x: u64) -> Foo { ... }
pub fn ignored() { ... } // wrong ABI
будет соответствовать
#ifndef FILENAME_H
#define FILENAME_H
#include<stdint.h>
struct Foo {
int16_t x;
}
struct Foo bar(uint64_t);
#endif
чтобы можно было легче вызывать Rust из C.
(Это обратная операция предлагаемой функциональности #[header="stdio.h"] mod stdio;
для использования libclang для чтения заголовков C в форму, которую понимает rustc: https://github.com/mozilla/rust/issues/2124)
В связи с этим я слышал, что иметь rust.h
было бы неплохо для таких вещей, как:
typedef struct {
void *data;
uintptr_t len;
} RustSlice;
typedef struct {
uintptr_t len;
uintptr_t alloc;
uint8_t data[0];
} RustString;
И другие полезные определения компилятора.
Одной из сложных частей этого будет представление C типов FFI, было бы очень приятно иметь возможность взаимодействовать с ними из C, но наши оптимизации будут обнуляемыми указателями, а размер дискриминанта может затруднить их.
:+1:
Я запустил версию этого на https://gist.github.com/alexcrichton/4ea33d9a8b19ed15a65a , но это всего лишь базовая инфраструктура для запуска чего-то подобного.
@alexcrichton Это довольно круто. Возможно, вы захотите придерживаться определения типов stdint.h
для печати целочисленных типов, поскольку ширина может варьироваться, а подписанность char
определяется реализацией.
/скопируйте меня
кое-что из этого делает bindgen, но rust.h
наверняка подойдет для FFI в Rust.
РЕДАКТИРОВАТЬ: упс, я думал, что bindgen сделал и то, и другое, но это не так, спасибо @huonw
(Вроде оффтоп: Bindgen даже не был подходящим ящиком для Rust, когда я последний раз проверял, и сборка его на Debian была достаточно болезненной, поэтому мне пришлось выбрать другой маршрут для моих нужд FFI. Желание иметь Bindgen-подобный Я думаю, что функциональность в dev-dependencies
— это, в первую очередь, желание, чтобы она была доступна build.rs
.
У меня есть кое-какие незавершенные работы. https://github.com/tomjakubowski/custard/tree/dev Я думаю, что в последний раз я оставил это, возможно, это было в середине рефакторинга.
Он следует той же идее, что и rustdoc: пройтись по типизированному AST, отфильтровать то, что нужно инструменту, немного очистить типы и создать что-то (заголовочный файл). Честно говоря, может иметь смысл сделать это «бэкендом» rustdoc или чем-то в этом роде (если вы прищуритесь, заголовочный файл — это просто еще один вид документации).
Я уверен, что все здесь уже в курсе, но современное состояние здесь похоже на ржавый чеддер: https://github.com/Sean1708/rusty-cheddar
ржавый чеддер и ржавый связующий не очень активны в эти дни. Должна ли эта функция быть настолько важной, чтобы Rust поддерживался rust-lang-nursery или чем-то подобным? @алекскрайтон
Закрытие; это должно быть решено внешним инструментом.
Самый полезный комментарий
Я уверен, что все здесь уже в курсе, но современное состояние здесь похоже на ржавый чеддер: https://github.com/Sean1708/rusty-cheddar