1 个不稳定版本

0.1.0 2024年6月28日

#336FFI

Download history 112/week @ 2024-06-23 30/week @ 2024-06-30 8/week @ 2024-07-07 6/week @ 2024-07-28 14/week @ 2024-08-04 52/week @ 2024-08-11

72 每月下载量
用于 2 crates

MIT/Apache

13KB
354

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 操作的槽指针和用户参数有效。这是通过实现一个原子槽结构并提供一个 [drop_safe] 属性来实现的,要求用户传递具有所有权的参数。

工具链要求

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

里程碑

初始版本

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

基本能力提升

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

性能优化

  • 基于共享内存的实现

扩展功能

  • 支持从 Golang 调用 Rust

致谢

本项目受到 fcplug 的启发。

无运行时依赖