12 个不稳定版本 (3 个破坏性版本)

0.3.9 2024年6月28日
0.3.8 2024年6月28日
0.3.4 2023年12月27日
0.2.0 2023年12月21日
0.0.2 2023年12月10日

#66 in #golang

Download history 17/week @ 2024-05-25 10/week @ 2024-06-01 6/week @ 2024-06-08 28/week @ 2024-06-15 285/week @ 2024-06-22 99/week @ 2024-06-29 9/week @ 2024-07-06 1/week @ 2024-07-13 67/week @ 2024-07-27 18/week @ 2024-08-03 51/week @ 2024-08-10 147/week @ 2024-08-17

每月284次下载
rust2go 中使用

MIT/Apache

81KB
1.5K SLoC

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>> 这样的结构体需要中间表示。为了将内存分配的数量减少到一次,我使用预计算的尺寸缓冲区来存储这些中间结构。

内存安全

在Go语言方面,它接收的数据来源于Rust。Rust方面将尽力确保在调用过程中该数据的有效性。因此,Go语言方面可以任意实现处理程序,但在将数据泄露到函数生命周期之外时,需要手动进行深度复制。

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

工具链要求

  • Go语言:>=1.18
    • 对于 >=1.18 且 < 1.20:使用 --go118 生成Go代码
    • 对于 >=1.20:正常生成Go代码
  • Rust:如果您想使用async,则需要 >=1.75

里程碑

初始版本

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

基本能力增强

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

性能优化

  • 基于共享内存的实现

扩展功能

  • 支持从Go语言调用Rust

致谢

本项目受 fcplug 的启发。

依赖

~245–680KB
~16K SLoC