Por ejemplo,
#[crate_type="lib"];
pub struct Foo { x: i16 }
#[no_mangle]
pub extern "C" fn bar(x: u64) -> Foo { ... }
pub fn ignored() { ... } // wrong ABI
correspondería a
#ifndef FILENAME_H
#define FILENAME_H
#include<stdint.h>
struct Foo {
int16_t x;
}
struct Foo bar(uint64_t);
#endif
para que uno pueda llamar a Rust desde C más fácilmente.
(Esta es la operación inversa de la funcionalidad propuesta #[header="stdio.h"] mod stdio;
para usar libclang para leer encabezados C en una forma que rustc entienda: https://github.com/mozilla/rust/issues/2124)
En este sentido, he oído que sería bueno tener un rust.h
para cosas como:
typedef struct {
void *data;
uintptr_t len;
} RustSlice;
typedef struct {
uintptr_t len;
uintptr_t alloc;
uint8_t data[0];
} RustString;
Y otras definiciones útiles del compilador.
Una parte difícil de esto sería la representación C de los tipos de FFI, sería muy bueno poder interactuar con ellos desde C, pero nuestras optimizaciones serán punteros anulables y el tamaño discriminante puede dificultarlos.
:+1:
Comencé una versión de esto en https://gist.github.com/alexcrichton/4ea33d9a8b19ed15a65a , pero es solo la infraestructura básica para poner en marcha algo como esto.
@alexcrichton Eso es genial. Es posible que desee ceñirse al uso de las definiciones de tipo stdint.h
para imprimir los tipos enteros, ya que los anchos pueden variar y el signo de char
está definido por la implementación.
/cc mí
bindgen hace algo de esto, pero rust.h
sería bueno para FFIing en Rust seguro
EDITAR: Vaya, pensé que bindgen hizo ambas cosas, pero no es así, gracias @huonw
(Fuera de tema, más o menos: Bindgen ni siquiera era una caja de Rust adecuada, la última vez que lo comprobé, y construirlo en Debian fue tan doloroso que tuve que elegir otra ruta para mis necesidades de FFI. El deseo de tener un tipo de bindgen Creo que la funcionalidad en Rust es principalmente un deseo de tenerlo disponible en todas partes. Podría satisfacerse con bindgen funcionando como un paquete Cargo dev-dependencies
adecuado capaz de generar los resguardos de Rust desde un encabezado C completamente desde build.rs
). UPS. Eso fue una diatriba. : }
Tengo algunas cosas WIP aquí. https://github.com/tomjakubowski/custard/tree/dev Creo que lo último que lo dejé, puede haber sido en medio de un refactor.
Sigue la misma idea que rustdoc: recorra el AST escrito, filtre las cosas que le importan a la herramienta, limpie un poco los tipos y emita algo (un archivo de encabezado). Con toda honestidad, podría tener sentido hacer de esto un 'backend' de rustdoc o algo así (si entrecierra los ojos, un archivo de encabezado es solo otro tipo de documentación).
Estoy seguro de que todos aquí ya lo saben, pero el estado del arte aquí parece ser rusty-cheddar: https://github.com/Sean1708/rusty-cheddar
rusty-cheddar y rusty-binder no son muy activos en esos días. ¿Debería ser esta una característica lo suficientemente importante como para que Rust sea mantenido por rust-lang-nursery o algo así? @alexcrichton
Clausura; esto debe ser abordado por una herramienta externa.
Comentario más útil
Estoy seguro de que todos aquí ya lo saben, pero el estado del arte aquí parece ser rusty-cheddar: https://github.com/Sean1708/rusty-cheddar