2 个版本
0.1.2 | 2020年7月1日 |
---|---|
0.1.0 | 2020年6月30日 |
#451 in 过程宏
70KB
2K SLoC
DUSTR
使用 dustr
,您可以从 Dart 调用此 Rust 代码
#[ffishim_function]
fn hello(s: String) -> String {
format!("Hello, {}!", s)
}
from dart
import 'package:hello/hello.dart';
void main() {
var greeting = hello("fred");
print("${greeting}");
}
dustr
是一个二进制文件,它解析 Rust 代码以生成其 Dart 绑定。Rust 代码必须使用来自 ffishim_derive 的过程宏从 ffishim 库进行标记。
这些过程宏生成一个与原始数据结构/函数兼容的 FFI API。这是必要的,因为许多基本的 Rust 类型(String
、Option
、Vec
等)不遵循 C ABI。
安装与使用
现在,假设我们想重现我们的第一个例子。我们需要 make、cargo 和 Dart SDK。我们使用 cargo 安装 dustr
export PATH=$PATH:$HOME/.cargo/bin
cargo install dustr
我们还创建了自己的 hello crate,并将其标记为 C 动态库(cdylib,在 rusthello/target/debug
目录中生成 .so
共享对象)
cargo new --lib rusthello --name hello
cat >>rusthello/Cargo.toml <<EOF
ffishim = "^0"
ffishim_derive = "^0"
[lib]
crate-type = ["cdylib"]
EOF
cat >rusthello/src/lib.rs <<EOF
#[macro_use]
extern crate ffishim_derive;
#[ffishim_library]
#[ffishim_function]
fn hello(s: String) -> String {
format!("Hello, {}!", s)
}
EOF
cargo build --manifest-path=rusthello/Cargo.toml
ls rusthello/target/debug/libhello.so
我们趁机添加了代码(这次增加了更多的管道),并构建了库。现在让我们进入 Dart 部分...
dustr --dest darthello --name hello rusthello/
cd darthello; pub get; cd -
dustr
命令将创建一个包含对 rusthello 库绑定的 Dart 包。使用 pub get
拉取任何依赖项。我们现在将设置 Dart 应用程序,它将使用我们的绑定
mkdir -p dartapp/bin
cat >dartapp/bin/main.dart <<EOF
import 'package:hello/hello.dart';
void main() {
var greeting = hello("fred");
print("\${greeting}");
}
EOF
cat >dartapp/pubspec.yaml <<EOF
---
name: app
dependencies:
hello:
path: ../darthello
environment:
sdk: ">=2.0.0 <3.0.0"
EOF
cd dartapp; pub get; cd -
现在我们可以运行应用程序。不要忘记提供 Rust 库
LD_LIBRARY_PATH=rusthello/target/debug dart dartapp/bin/main.dart
示例
您可以通过查看 tests
文件夹来找到 dustr
的行为示例。测试的结构如下
src/lib.rs
:要公开的 Rust 库Cargo.toml
:Rust 库的清单(定义了 cdylib 等..)pubspec.yaml
:dart二进制文件的清单(定义了依赖生成的绑定)bin/main.dart
:使用此Rust库的dart代码expected_output
:包含运行C程序预期的输出
每个测试文件夹都是一个独立的应用程序。例如,你可以
- 运行
make
来测试所有这些 - 在
target/bindings
层级中检查生成的绑定代码 - 调整一个或两个测试来尝试行为并重新运行
make
来测试 - 将它们用作模板来创建自己的Rust <-> dart集成
C ABI免责声明
由于dart ffi支持仍处于alpha阶段,它还不能完全消费C ABI。例如,它不支持嵌套结构,并且结构不能按值传递给函数。因此,我们使用的ffishim crate不会生成C-ABI代码,而是一个由dart ffi可消费的版本。
TODO/限制
此crate仍处于beta阶段。它还不适合用于生产。
错误
- 修复不在struct/enum内时返回字符串的泄露
- 修复不在struct/enum内时返回选项的泄露
特性
- 适应ffishim中的潜在名称修饰(以避免重复)
- 找到usize/isize/char的dart类型等效物
- 实现DateTime行为
测试
- 添加一个“完整”的测试/示例情况
- 按领域重新组织测试(找到分类法)
- 对一些用例进行基准测试
文档
- 在README.md简介中写明此crate的功能
- 在哪里写入doc.rs中的二进制文档?
依赖项
~5.5MB
~110K SLoC