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
每月284次下载
在 rust2go 中使用
81KB
1.5K SLoC
Rust2Go
Rust2Go是一个项目,为用户提供了一种简单高效的方法来从Rust调用Golang,并支持原生的异步操作。
特性
- Rust到Golang的同步和异步调用
- 高效的数据交换:没有序列化或套接字通信,而是使用FFI
- 简单的接口设计:除了原生的Rust外,不需要新的IDL
使用方法
- 使用限制性Rust语法定义结构体和调用接口,并将生成的代码包含在同一文件中。
- 使用以下命令生成Golang代码:
rust2go-cli --src src/user.rs --dst go/gen.go
- 为您项目编写一个
build.rs
文件。 - 然后您可以使用生成的实现来在您的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代码
- 对于 >=1.18 且 < 1.20:使用
- Rust:如果您想使用async,则需要 >=1.75
里程碑
初始版本
- IDL(Rust)解析
- Go代码生成
- 构建脚本助手
- 基本数据类型和转换生成
- Rust实现生成
- 使用future和基本同步原语
基本能力增强
- 支持更复杂的数据类型
- 支持用户传递引用
- 更优雅的代码生成实现
- 更好的构建缓存控制
- 支持Go语言接口(将用户代码与生成代码分开)
- 动态链接支持
- Go语言辅助库
性能优化
- 基于共享内存的实现
扩展功能
- 支持从Go语言调用Rust
致谢
本项目受 fcplug 的启发。
依赖
~245–680KB
~16K SLoC