15 个版本

0.3.15 2024 年 7 月 24 日
0.3.8 2024 年 4 月 11 日
0.3.7 2024 年 3 月 4 日
0.3.5 2023 年 12 月 27 日

#80FFI

Download history 1/week @ 2024-05-16 9/week @ 2024-05-23 16/week @ 2024-05-30 5/week @ 2024-06-06 6/week @ 2024-06-13 55/week @ 2024-06-20 526/week @ 2024-06-27 137/week @ 2024-07-04 90/week @ 2024-07-18 206/week @ 2024-07-25 35/week @ 2024-08-01 41/week @ 2024-08-08 92/week @ 2024-08-15

每月 465 次下载

MIT/Apache

34KB
859

Rust2Go

Crates.io

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

特性

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

如何使用

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

有关详细示例,请查看 示例项目

关键设计

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

为什么速度快?

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

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

内存安全

在Golang方面,它接收的数据是从Rust引用的。Rust方面将尽力确保在调用期间数据的有效性。因此,Golang方面可以任意实现处理器,但在函数生命周期外泄露数据时需要手动深度复制。

在Rust方面,需要在回调ffi操作槽指针和用户参数在future结束时有效。这是通过实现原子槽结构并提供一个[drop_safe]属性来实现的,该属性要求用户以所有者身份传递参数。

工具链要求

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

里程碑

初始版本

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

基本功能增强

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

性能优化

  • 基于共享内存的实现

扩展功能

  • 支持从Golang调用Rust

致谢

本项目受到fcplug的启发。

依赖关系

~0.3–11MB
~125K SLoC