Flutter跨语言通信插件flutter_rust_bridge的使用

发布于 1周前 作者 songsunli 来自 Flutter

Flutter跨语言通信插件flutter_rust_bridge的使用

简介

flutter_rust_bridge 是一个用于Flutter/Dart和Rust之间绑定生成的工具,它功能丰富但无缝且简单。通过这个工具,你可以轻松地在Flutter项目中调用Rust代码,或者让Rust代码调用Dart函数。

项目特性

新增特性(V2)

  • 快速设置:只需一条命令即可集成到项目中。
  • 任意类型:支持任意Rust和Dart类型,无需手动干预。
  • 异步Rust:支持异步Rust函数。
  • Rust调用Dart:允许Rust调用Dart函数。
  • 支持整个文件夹作为输入:可以处理整个文件夹而不是单个文件。
  • 使用库/工具:所有现有的库和调试工具都可以正常使用。

快速开始

创建并运行一个包含Flutter + Rust的应用程序:

cargo install flutter_rust_bridge_codegen && flutter_rust_bridge_codegen create my_app && cd my_app && flutter run

可选步骤: 编辑 rust/src/api/simple.rs 文件(例如将 Hello 改为 Hi),然后运行以下命令查看更改效果:

flutter_rust_bridge_codegen generate && flutter run

更多详细的快速启动指南请访问 官方文档

示例代码

示例1

简单的Rust函数…

fn f(a: String, b: Vec<MyEnum>) -> MyStruct { ... }

…可以在Dart中无缝调用:

print(f(a: 'Hello', b: [MyEnum.c('Tom')]));

示例2

假设我们在Rust中实现了一个单词词典:

// ↱ 可以使用任意复杂的Rust类型
pub struct WordDict { .. }

// ↱ 支持函数 & 方法
impl WordDict {
    //          ↱ 可以回调Dart                 ↱ 翻译错误
    pub fn open(chooser: impl Fn(String) -> bool) -> Result<WordDict> { .. }

    // ↱ 支持同步与异步Dart;属性获取器
    #[frb(sync, getter)]
    //          ↱ 支持T/&T/&mut T
    pub fn size(&self) -> u32 { .. }

    //  ↱ 允许异步 & 同步                    ↱ 支持流(迭代器)
    pub async fn search(&self, keyword: String, sink: StreamSink<String>) { .. }
}

同样可以在Dart中无缝调用:

final dict = await WordDict.open((situation) => true);
print(dict.size);
await for (final value in dict.search('something')) { print(value); }

这些示例展示了如何轻松地在Flutter应用程序中使用高性能的Rust代码,而无需担心底层的复杂性。

完整示例项目

为了帮助理解如何在实际项目中使用 flutter_rust_bridge,这里提供了一个完整的示例项目结构:

项目结构

my_app/
├── android/
├── ios/
├── lib/
│   └── main.dart
├── rust/
│   ├── Cargo.toml
│   ├── build.rs
│   └── src/
│       └── api/
│           └── simple.rs
└── pubspec.yaml

配置步骤

  1. 安装依赖

    在项目的根目录下运行以下命令来安装必要的工具链:

    cargo install flutter_rust_bridge_codegen
    
  2. 初始化项目

    使用提供的脚本初始化一个新的Flutter + Rust项目:

    flutter_rust_bridge_codegen create my_app
    
  3. 编写Rust代码

    编辑 rust/src/api/simple.rs 文件,添加你想要的功能。例如:

    pub fn greet(name: &str) -> String {
        format!("Hello, {}!", name)
    }
    
  4. 生成绑定代码

    运行以下命令生成绑定代码:

    flutter_rust_bridge_codegen generate
    
  5. 编写Dart代码

    lib/main.dart 中调用生成的Rust函数:

    import 'package:flutter/material.dart';
    import 'package:my_app/generated_bridge.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(title: Text('Flutter Rust Bridge Example')),
            body: Center(
              child: ElevatedButton(
                onPressed: () {
                  final result = greet("World");
                  print(result); // 输出 "Hello, World!"
                },
                child: Text('Press me'),
              ),
            ),
          ),
        );
      }
    }
    
  6. 运行项目

    最后,在终端中运行:

    flutter run
    

    这将编译并启动你的应用程序,你应该能够在按下按钮后看到控制台输出 “Hello, World!”。

总结

flutter_rust_bridge 提供了一种强大且简便的方法来连接Flutter和Rust世界。通过上述步骤,你可以快速上手并在自己的项目中应用这一工具。更多高级特性和详细信息,请参考 官方文档


更多关于Flutter跨语言通信插件flutter_rust_bridge的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter跨语言通信插件flutter_rust_bridge的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用flutter_rust_bridge插件来实现跨语言通信的示例代码。flutter_rust_bridge是一个强大的工具,允许Flutter与Rust进行高效、安全的通信。以下示例将展示如何在Flutter端调用Rust端的函数,并将结果返回给Flutter。

1. 设置项目

首先,你需要创建一个新的Flutter项目,并添加flutter_rust_bridge依赖。

flutter create flutter_rust_bridge_example
cd flutter_rust_bridge_example

pubspec.yaml文件中添加flutter_rust_bridge依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_rust_bridge: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来安装依赖。

2. 配置Rust环境

android目录下,创建一个CMakeLists.txt文件用于构建Rust代码。同时,你需要一个Rust库来与Flutter通信。

创建Rust库

在项目根目录下创建一个rust文件夹,并在其中创建Cargo.tomlsrc/lib.rs文件。

rust/Cargo.toml

[package]
name = "flutter_rust_bridge_ffi"
version = "0.1.0"
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]

rust/src/lib.rs

#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
    a + b
}

创建CMakeLists.txt

android目录下创建CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

add_library(flutter_rust_bridge_ffi SHARED
            ../rust/target/release/libflutter_rust_bridge_ffi.so)

find_library(log-lib log)

target_link_libraries(flutter_rust_bridge_ffi ${log-lib})

注意:你需要手动构建Rust库,并将其.so文件放在正确的位置。你可以使用以下命令构建Rust库:

cd rust
cargo build --release --target=armv7-linux-androideabi30  # 根据你的目标平台调整
cp target/release/libflutter_rust_bridge_ffi.so ../android/app/src/main/jniLibs/armeabi-v7a/

3. 编写Flutter代码

在Flutter项目中,你需要编写代码来加载Rust库并调用其函数。

生成FFI绑定

首先,使用flutter_rust_bridge的工具生成FFI绑定。由于这个步骤涉及较复杂的配置和命令行操作,这里假设你已经按照flutter_rust_bridge的文档生成了必要的Dart和Rust代码。

调用Rust函数

lib/main.dart中编写代码来加载并调用Rust函数:

import 'dart:ffi';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Rust Bridge Example'),
        ),
        body: Center(
          child: RustBridgeExample(),
        ),
      ),
    );
  }
}

class RustBridgeExample extends StatefulWidget {
  @override
  _RustBridgeExampleState createState() => _RustBridgeExampleState();
}

class _RustBridgeExampleState extends State<RustBridgeExample> {
  late DynamicLibrary _rustLibrary;

  @override
  void initState() {
    super.initState();
    _loadRustLibrary();
  }

  void _loadRustLibrary() async {
    _rustLibrary = await FlutterRustBridge.loadLibrary(
      name: 'flutter_rust_bridge_ffi',
    );
  }

  void _callRustFunction() {
    final Int32List args = Int32List(2).withValues(5, 3);
    final Pointer<Int32> argPtr = args.asPointer();
    final Pointer<Int32> resultPtr = Pointer.allocate<Int32>();

    // 假设add函数的签名已经通过flutter_rust_bridge生成并绑定
    final addFunc = _rustLibrary
        .lookup<NativeFunction<Void Function(Pointer<Int32>, Pointer<Int32>, Pointer<Int32>)>>('add')
        .asFunction<Void Function(Pointer<Int32>, Pointer<Int32>, Pointer<Int32>)>();

    addFunc(argPtr, Pointer.fromAddress(0), resultPtr);  // 第二个参数为null指针,根据实际需求调整

    final int result = resultPtr.value;
    print('Result from Rust: $result');
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Press the button to call Rust function'),
        ElevatedButton(
          onPressed: _callRustFunction,
          child: Text('Call Rust'),
        ),
      ],
    );
  }
}

注意:上面的代码是一个简化的示例,实际使用中你可能需要处理更多的细节,比如错误处理、内存管理等。同时,flutter_rust_bridge的使用可能需要更复杂的配置和生成步骤,请参考其官方文档获取详细指导。

这个示例展示了如何在Flutter中加载Rust库并调用其函数。在实际项目中,你可能需要处理更复杂的数据类型和交互逻辑。

回到顶部