例如,
#[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
这样人们就可以更轻松地从 C 调用 Rust。
(这是建议的#[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;
以及其他有用的编译器定义。
关于这方面的一个困难部分是 FFI 类型的 C 表示,能够从 C 中与它们进行交互会非常好,但是我们的优化将使可空指针和判别大小可能使它们变得困难。
:+1:
我在https://gist.github.com/alexcrichton/4ea33d9a8b19ed15a65a开始了这个版本,但它只是让这样的东西启动并运行的最基本的基础设施。
@alexcrichton那太酷了。 您可能希望坚持使用stdint.h
类型定义来打印整数类型,因为宽度可以变化并且char
的符号是实现定义的。
/抄送我
bindgen 做了一些这样的事情,但是rust.h
对于 FFI 进入 Rust 肯定会很好
编辑:哎呀,我认为 bindgen 两者都做了,但事实并非如此,谢谢@huonw
(题外话,有点:Bindgen 甚至不是一个合适的 Rust 板条箱,上次我检查时,在 Debian 上构建它已经够痛苦了,我不得不为我的 FFI 需求选择另一条路线。希望拥有类似 bindgen我认为,Rust 中的功能主要是希望让它随处可用。它可以满足于 bindgen 作为适当的 Cargo dev-dependencies
包,能够完全从build.rs
从 C 标头生成 Rust 存根
我这里有一些 WIP 的东西。 https://github.com/tomjakubowski/custard/tree/dev我想我最后离开了它,它可能正在重构中。
它遵循与 rustdoc 相同的想法:遍历类型化的 AST,过滤掉工具关心的东西,稍微清理类型,然后发出一些东西(头文件)。 老实说,将其作为 rustdoc 的“后端”或其他东西可能是有意义的(如果你眯着眼睛,头文件只是另一种文档)。
我敢肯定这里的每个人都已经意识到了,但这里的最新技术似乎是 rusty-cheddar: https ://github.com/Sean1708/rusty-cheddar
那些日子生锈的切达干酪和生锈的粘合剂不是很活跃。 这是否应该是一个足够重要的功能,足以让 Rust 由 rust-lang-nursery 等来维护? @alexcrichton
关闭; 这应该通过外部工具来解决。
最有用的评论
我敢肯定这里的每个人都已经意识到了,但这里的最新技术似乎是 rusty-cheddar: https ://github.com/Sean1708/rusty-cheddar