【问题标题】:How to call Rust functions in Flutter (Dart) via FFI, but with convenience and safety?如何通过 FFI 在 Flutter (Dart) 中调用 Rust 函数,但又方便又安全?
【发布时间】:2021-10-07 01:29:54
【问题描述】:

我知道我们可以通过 FFI 从 Flutter/Dart 调用 Rust。但是 Flutter 在做 FFI 时只允许使用 C ABI。因此,我必须手动写下样板代码。特别是 Rust unsafe 代码 - 因为我必须处理大量原始指针:(

因此,有什么方法可以安全地做到这一点吗?我们知道 Rust 本身非常安全(因为它独特的内存管理方法),Dart/Flutter 本身也非常安全(因为 GC)。但我不希望 ffi 调用成为致命弱点并破坏我的应用程序的安全性!

【问题讨论】:

    标签: flutter dart rust ffi


    【解决方案1】:

    有几种方法可以做到。

    一个。基于 JSON/Protobuf 的方法

    我在生产环境中使用了一年的第一种方式是,您可以使用 JSON 或 Protobuf 在 Rust 和 Dart/Flutter 之间传递所有数据。通过这样做,您无需写下大量样板代码来分配/释放字符串、字节列表、结构/类等。您需要做的就是写下 一个 接受字节数组有效负载并输出字节数组结果的单个函数。通过说“一个”函数,我的意思是,您可以在 JSON/Protobuf 中有一个 action 字段,因此可以将对不同 Rust 函数的调用交错到这个薄接口中。

    尽管它很方便(只有一点不安全样板),但缺点也很明显。序列化和反序列化不是免费的。您将不得不为此支付 CPU 时间和内存,这有时会非常大。此外,您不能轻易绕过大物体。例如,如果你有一个图像(你知道,至少有兆字节的大小),将其序列化为 Protobuf,然后从 Protobuf 反序列化它可能会浪费 CPU 和内存——无用的副本!更糟糕的是,由于 Flutter/Dart FFI 不支持方便的异步 FFI 方式,您必须使其在单独的工作隔离中运行 - 多一份内存副本。你可以在这里看到更多:https://github.com/dart-lang/language/issues/1862(这是我打开的一个问题)。

    b.代码生成器

    我最近使用的第二种方法是编写代码生成器。事实上,代码遵循几种常见的模式,例如“分配 - 填充数据 - 调用 FFI - 免费”等。因此编写生成器来自动执行此类操作并不难。这个想法是模仿人类在手动编写样板代码时会做什么。

    我确实希望已经有一些代码生成器可以直接使用,但似乎没有......所以,你自己去写吧。

    c。使用现有的开源代码生成器

    写完代码生成器,估计大家也有和我一样的问题,所以开源了:https://github.com/fzyzcjy/flutter_rust_bridge

    确实,我的代码生成器不仅解决了上面的问题,而且有丰富的类型支持,允许零拷贝,允许异步编程和从主隔离直接调用等,可以通过代码生成器实现,但需要很多样板代码,如果你手动做的话。

    免责声明:这是一个问答式的答案,以展示我的想法以及我在这个问题上所做的工作,这对我自己的生产环境中的应用程序至关重要。事实上,我从去年开始就使用 JSON 方法,后来重构为代码生成器方法。希望它也能帮助其他面临同样情况的人!

    【讨论】:

      猜你喜欢
      • 2018-01-14
      • 1970-01-01
      • 1970-01-01
      • 2012-09-05
      • 2015-11-01
      • 2020-08-15
      • 1970-01-01
      • 2021-06-12
      • 1970-01-01
      相关资源
      最近更新 更多