- Published on
Dart 调用 Rust 代码:跨平台实践 (iOS & Android)
- Authors
- Name
- Alex
- @adams6688
如何使用 Dart 来调用 Rust 的代码?
在 Dart 中调用 Rust 代码通常可以通过以下几种方式来实现:
1. 使用 FFI(Foreign Function Interface)
Dart 提供了 dart:ffi
库来调用本地共享库(如 .dll
, .so
, .dylib
),Rust 可以编译为共享库以供 Dart 调用。
基本步骤
Step 1: 编写 Rust 代码
Rust 代码示例 (src/lib.rs
):
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
a + b
}
编译为共享库
# Linux/macOS
cargo build --release
# Windows
cargo build --release --target x86_64-pc-windows-gnu
在 target/release
中会生成以下文件:
- Linux:
libmy_rust_lib.so
- macOS:
libmy_rust_lib.dylib
- Windows:
my_rust_lib.dll
Step 2: Dart 调用 Rust
在 Dart 项目中:
import 'dart:ffi' as ffi;
import 'dart:io';
typedef AddFunc = ffi.Int32 Function(ffi.Int32, ffi.Int32);
typedef Add = int Function(int, int);
void main() {
final lib = ffi.DynamicLibrary.open(
Platform.isWindows ? 'my_rust_lib.dll' :
Platform.isMacOS ? 'libmy_rust_lib.dylib' :
'libmy_rust_lib.so');
final addPointer = lib.lookup<ffi.NativeFunction<AddFunc>>('add');
final add = addPointer.asFunction<Add>();
final result = add(3, 5);
print('3 + 5 = $result');
}
2. 使用 Flutter + Rust
如果你正在做 Flutter 开发,推荐使用 flutter_rust_bridge
这个库,它可以帮助你更高效、简洁地将 Rust 与 Flutter 集成。
简要流程
- 安装
flutter_rust_bridge
- 编写
Rust
代码并生成API
- Flutter 中调用 Rust 逻辑
工具推荐
flutter_rust_bridge
: Flutter 与 Rust 的桥梁。dart:ffi
: Dart 官方的 FFI 库。
Rust 是否可以编译成兼容 iOS 和 Android 平台的代码?
是的,Rust 可以编译成兼容 iOS 和 Android 平台的代码,并且可以通过 FFI 与 Dart(Flutter)无缝集成。Rust 拥有强大的跨平台能力,并且可以通过交叉编译为 Android 和 iOS 提供共享库,从而供 Flutter 或其他移动应用调用。
🛠️ 1. 编译 Rust 代码以兼容 iOS 和 Android
1.1 编译 Rust 代码以支持 Android
💾 设置环境
安装 Android NDK(Native Development Kit):
- 下载 Android NDK:通过 NDK 下载页面 或 Android Studio 的 SDK Manager。
- 设置环境变量:
export ANDROID_NDK_HOME=$HOME/Android/Sdk/ndk/25.2.9519653
安装 Rust 的 Android 目标架构:
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android
📜 编写 Rust 代码
创建 src/lib.rs
:
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
a + b
}
Cargo.toml
[lib]
name = "my_rust_lib"
crate-type = ["cdylib"]
[dependencies]
⚙️ 编译为 Android 的共享库
运行以下命令:
# 编译 ARM64(Android)
cargo build --release --target aarch64-linux-android
生成的库文件位于:
target/aarch64-linux-android/release/libmy_rust_lib.so
💡说明: Android 平台使用 .so
文件,且必须将库文件放入 android/app/src/main/jniLibs
目录中,按 CPU 架构区分子目录:
jniLibs
├── arm64-v8a # 对应 aarch64-linux-android
│ └── libmy_rust_lib.so
├── armeabi-v7a # 对应 armv7-linux-androideabi
│ └── libmy_rust_lib.so
├── x86_64 # 对应 x86_64-linux-android
│ └── libmy_rust_lib.so
1.2 编译 Rust 代码以支持 iOS
💾 设置环境
安装 iOS 编译目标:
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
确保安装了 Xcode,并通过以下命令确认:
xcode-select --install
📜 编写 Rust 代码
使用与 Android 相同的 src/lib.rs
文件:
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
a + b
}
Cargo.toml
[lib]
name = "my_rust_lib"
crate-type = ["cdylib"]
[dependencies]
⚙️ 编译为 iOS 的共享库
# 编译 iOS(真机)
cargo build --release --target aarch64-apple-ios
# 编译 iOS 模拟器(M1/M2 芯片)
cargo build --release --target aarch64-apple-ios-sim
# 编译 iOS 模拟器(Intel 芯片)
cargo build --release --target x86_64-apple-ios
生成的库文件:
- iOS 设备:
target/aarch64-apple-ios/release/libmy_rust_lib.a
- iOS 模拟器:
target/aarch64-apple-ios-sim/release/libmy_rust_lib.a
💡 说明: iOS 平台使用 .a
静态库而不是 .so
。
1.3 iOS/Android 编译的关键差异
特性 | Android | iOS |
---|---|---|
库文件后缀 | .so | .a (静态库) |
架构 | arm64-v8a , x86_64 | aarch64 , x86_64 |
调用方式 | DynamicLibrary.open | DynamicLibrary.process |
NDK 依赖 | 需要 | 不需要 |
🚀 2. Dart/Flutter 中调用 Rust
2.1 调用 Android 的 Rust 代码
Dart 调用 Android Rust 共享库的示例:
import 'dart:ffi';
import 'dart:io';
typedef AddFunc = Int32 Function(Int32, Int32);
typedef Add = int Function(int, int);
void main() {
final lib = DynamicLibrary.open('libmy_rust_lib.so');
final addPointer = lib.lookup<NativeFunction<AddFunc>>('add');
final add = addPointer.asFunction<Add>();
final result = add(5, 7);
print('5 + 7 = $result');
}
运行时注意: Android 上 .so
文件需放在 android/app/src/main/jniLibs
目录下。Flutter 会自动打包该目录内的 .so
文件到最终的 APK。
2.2 调用 iOS 的 Rust 代码
Dart 调用 iOS Rust 静态库的示例:
import 'dart:ffi';
typedef AddFunc = Int32 Function(Int32, Int32);
typedef Add = int Function(int, int);
void main() {
final lib = DynamicLibrary.process();
final addPointer = lib.lookup<NativeFunction<AddFunc>>('add');
final add = addPointer.asFunction<Add>();
final result = add(5, 7);
print('5 + 7 = $result');
}
运行时注意:
- 需要将
libmy_rust_lib.a
添加到 Xcode 项目中的Link Binary With Libraries
。 - Dart 调用 iOS 的 Rust 函数时应使用
DynamicLibrary.process()
,因为 iOS 不允许动态加载自定义共享库。
flutter_rust_bridge
🧩 3. 高效集成:如果你是 Flutter 开发者,建议使用 flutter_rust_bridge
库。它封装了 Dart 与 Rust 之间的通信,避免了手动管理 FFI 和平台兼容性的问题。
快速步骤:
添加依赖:
dependencies: flutter_rust_bridge: ^1.0.0
使用
flutter_rust_bridge_codegen
工具自动生成跨语言接口代码。跨平台调用 Rust 逻辑时,代码完全无感知。
🧐 4. 常见问题与优化
跨平台架构支持不足:
- Android 支持
arm64-v8a
,armeabi-v7a
,x86
,x86_64
。 - iOS 支持
aarch64
、x86_64
(模拟器)。
- Android 支持
性能考虑:
- Rust 和 Dart 之间通过 FFI 调用有一定开销,建议避免频繁调用小函数。
- 尝试将高频逻辑尽可能在 Rust 端完成,Dart 只调用最终结果。
安全性:
- Rust 是内存安全语言,但通过 FFI 调用仍需谨慎,避免不安全的指针传递。
动态库加载失败:
- Android:确保
jniLibs
目录中有正确的.so
文件。 - iOS:检查是否已正确链接
libmy_rust_lib.a
。
- Android:确保
🎯 5. 结论
Rust 具备良好的跨平台能力,可以高效地为 iOS 和 Android 编译共享库,并能通过 Dart 的 dart:ffi
调用这些库,实现性能和安全性的双赢。
🔹 Android:生成 .so
文件,放置于 jniLibs
。 🔹 iOS:生成 .a
文件,添加至 Xcode。 🔹 推荐工具:flutter_rust_bridge
简化开发流程。
Rust 的强大性能与 Flutter 的跨平台优势相结合,为开发高性能、跨平台的移动应用提供了强有力的支持。 😊