14个不稳定版本 (3个重大更新)

0.3.10 2024年6月29日
0.3.9 2024年6月28日
0.3.6 2024年3月14日
0.3.4 2023年12月27日
0.0.2 2023年12月10日

#210 in FFI

Download history 1/week @ 2024-05-14 6/week @ 2024-05-21 30/week @ 2024-05-28 13/week @ 2024-06-04 16/week @ 2024-06-11 75/week @ 2024-06-18 479/week @ 2024-06-25 51/week @ 2024-07-02 8/week @ 2024-07-09 6/week @ 2024-07-16 5/week @ 2024-07-23 52/week @ 2024-07-30 34/week @ 2024-08-06 57/week @ 2024-08-13

每月150次下载
用于 3 个crate(其中2个直接使用)

MIT/Apache

73KB
1.5K SLoC

Rust2Go

Crates.io

Rust2Go是一个项目,它为用户提供了一种简单高效的方法,从Rust调用Golang,并支持原生的异步操作。

特性

  • Rust到Golang的同步和异步调用
  • 高效的数据交换:没有序列化或套接字通信,而是使用FFI
  • 简单的接口设计:除了本地的Rust外,没有新的IDL

如何使用

  1. 在受限的Rust语法中定义结构体和调用接口,并将生成的代码包含在同一文件中。
  2. 使用rust2go-cli --src src/user.rs --dst go/gen.go生成golang代码
  3. 为你项目编写build.rs
  4. 然后你可以在Rust项目中使用生成的实现来调用golang!

有关详细示例,请参阅示例项目

关键设计

详细设计细节可以在本文中找到: Rust-Go FFI框架的设计与实现

为什么快?

为了达到最佳性能,本项目不基于通信,而是基于FFI来传递特殊编码的数据。为了将内存操作减少到最小,满足特定内存布局的数据通过引用直接传递,而不是复制。

例如,Vec<u8>String 被表示为指针和长度。然而,像 Vec<String>Vec<Vec<u8>> 这样的结构需要中间表示。为了将内存分配次数减少到一次,我使用一个预计算的大小缓冲区来存储这些中间结构。

内存安全

在 Golang 一侧,它接收到的数据来自 Rust。Rust 一侧将尽力确保在调用期间数据的有效性。因此,Golang 一侧可以任意实现处理程序,但在将数据泄漏到函数生命周期之外时需要手动深拷贝。

在 Rust 一侧,需要在未来释放时确保回调 ffi 操作的槽指针和用户参数是有效的。这是通过实现原子槽结构和提供 [drop_safe] 属性来要求用户传递具有所有权的参数来实现的。

工具链要求

  • Golang: >=1.18
    • 对于 >=1.18 && < 1.20:使用 --go118 生成 golang 代码
    • 对于 >=1.20:正常生成 golang 代码
  • Rust: >=1.75 如果要使用异步

里程碑

初始版本

  • IDL(在 rust 中解析)
  • Go 代码生成
  • 构建脚本助手
  • 基本数据类型和转换生成
  • Rust 实现
  • Future 和基本同步原语的使用

基本能力提升

  • 支持更复杂的数据类型
  • 支持用户传递引用
  • 更优雅的代码生成实现
  • 更好的构建缓存控制
  • Golang 接口支持(将用户代码与生成代码分开)
  • 动态链接支持
  • Golang 辅助库

性能优化

  • 基于共享内存的实现

扩展功能

  • 支持从 Golang 调用 Rust

致谢

本项目受到 fcplug 的启发。

依赖项

~275–730KB
~17K SLoC