Por exemplo,
#[crate_type="lib"];
pub struct Foo { x: i16 }
#[no_mangle]
pub extern "C" fn bar(x: u64) -> Foo { ... }
pub fn ignored() { ... } // wrong ABI
corresponderia a
#ifndef FILENAME_H
#define FILENAME_H
#include<stdint.h>
struct Foo {
int16_t x;
}
struct Foo bar(uint64_t);
#endif
para que se possa chamar Rust de C mais facilmente.
(Esta é a operação inversa da funcionalidade #[header="stdio.h"] mod stdio;
proposta para usar libclang para ler cabeçalhos C em um formulário que o rustc entende: https://github.com/mozilla/rust/issues/2124)
Nessa linha, ouvi dizer que ter um rust.h
seria bom para coisas como:
typedef struct {
void *data;
uintptr_t len;
} RustSlice;
typedef struct {
uintptr_t len;
uintptr_t alloc;
uint8_t data[0];
} RustString;
E outras definições úteis do compilador.
Uma parte difícil disso seria a representação C dos tipos FFI, seria muito bom poder interagir com eles a partir do C, mas nossas otimizações serão ponteiros anuláveis e o tamanho discriminante pode torná-los difíceis.
:+1:
Eu comecei uma versão disso em https://gist.github.com/alexcrichton/4ea33d9a8b19ed15a65a , mas é apenas a infraestrutura básica para colocar algo assim em funcionamento.
@alexcrichton Isso é muito legal. Você pode querer usar o typedefs stdint.h
para imprimir os tipos inteiros, uma vez que as larguras podem variar e o sinal de char
é definido pela implementação.
/cc eu
bindgen faz um pouco disso, mas rust.h
seria bom para usar FFI em Rust com certeza
EDIT: opa, pensei que o bindgen fizesse as duas coisas, mas não, obrigado @huonw
(Offtopic, meio que: Bindgen não era nem uma caixa Rust adequada, da última vez que verifiquei, e construí-lo no Debian foi uma dor suficiente para que eu tivesse que escolher outra rota para minhas necessidades de FFI. A funcionalidade no Rust é, eu acho, principalmente um desejo de tê-lo disponível em todos os lugares. Poderia ser satisfeito com o bindgen funcionando como um pacote Cargo dev-dependencies
adequado capaz de gerar os stubs Rust de um cabeçalho C inteiramente de build.rs
). Ups. Isso foi um desabafo. : }
Eu tenho algumas coisas WIP aqui. https://github.com/tomjakubowski/custard/tree/dev Acho que da última vez que deixei, pode ter sido no meio de uma refatoração.
Segue a mesma ideia do rustdoc: percorrer o AST digitado, filtrar as coisas com as quais a ferramenta se preocupa, limpar um pouco os tipos e emitir algo (um arquivo de cabeçalho). Com toda a honestidade, pode fazer sentido fazer disso um 'back-end' do rustdoc ou algo assim (se você apertar os olhos, um arquivo de cabeçalho é apenas outro tipo de documentação).
Tenho certeza que todos aqui já estão cientes, mas o estado da arte aqui parece ser rusty-cheddar: https://github.com/Sean1708/rusty-cheddar
rusty-cheddar e rusty-binder não são muito ativos naqueles dias. Isso deve ser um recurso importante o suficiente para que o Rust seja mantido pelo rust-lang-nursery ou algo assim? @alexcrichton
Fechamento; isso deve ser resolvido por uma ferramenta externa.
Comentários muito úteis
Tenho certeza que todos aqui já estão cientes, mas o estado da arte aqui parece ser rusty-cheddar: https://github.com/Sean1708/rusty-cheddar