Anyone called Rust via FFI from Flutter?

Obviously yes. But I am in a position where the firm I work for in considering moving from Swift/SwiftUI iOS only to Flutter/C|C++ for "portability".

They know C and want to use it for the tight loops. I am the programming dogs body and am bringing up the possibility of using Rust instead of C/C++.

I am not sure the time is quite right, some use cases would help tip the scales. I am not going to advocate what is not a good business plan, naturally. I do not have enough information to see it through from where I stand now.

At this point of time, in our Swift/SwiftUI code development we are in debugging hell catching all the sorts of bugs Rust is designed to avoid (indexes being off and arrays being empty) so it is a good moment to speak up.

I have searched the forums here for flutter and there is not much, and what there is has no replies. Hoping that this time I might get some information......

basically use cargo ndk to build your Rust code, in Cargo.toml add crate-type as cdylib in [lib] section and then copy resulting lib into .\android\app\src\main\jniLibs into folder according to your arch
i.e. for emulator it is x86_64 while arm are arm64-v8a etc. (e.g. .\android\app\src\main\jniLibs\arm64-v8a)

With that you should be able to use DynamicLibrary.open to load your lib, follow dart FFI docs on what to do next (be sure you export Rust code with C calling convention i.e. extern "C")

P.s. I also made simple generator crate for dart sdk bindings https://github.com/DoumanAsh/dart-sys

1 Like

Hi!

I made something similar in my dart-sys, and even built idiomatic bindings to some of the API in dart.

If you intend to keep your bindings up to date (mine haven't been updated since I am no longer working with dart), let me know and I'd be glad to transfer ownership of dart-sys to you and then rework dart to reflect that.

On a separate note, I was under the impression that language extensions were not implemented for mobile platforms, only regular C ffi.

1 Like

flutter supports dart's FFI just fine.
And it is been for a while now, albeit I noticed some parts of library were cut. Not sure why, but in any case we are able to use FFI from android without troubles.

Regarding dart-sys I'm actually in the same position as I'm intending to support it as long as I have use it (it is pretty simple to update by just bumping crate version, but I still hasn't found time to automate it somehow) so up to you.

Oh it's good to know they implemented it. When I made my crate there was a pretty specific omission of support of language extensions (through dart_api.h). I still don't intend to continue using it though, but I have some time to update my bindings right now, so I might as well.

That confuses me. Flutter and Dart are joined at the hip. " Flutter apps are written in the Dart programming language"

So if flutter did not support the Dart FFI there would be astonishment on my part!

Can I expect friction if I try to call to Rust from Dart? On iOS, Android, and Windows (required by corporate overlords).

DoumanAsh suggests that it is straightforward enough on Android, if I understand.

My initial impression is that this is all quite immature. Would that be fair enough? I am coming to the party too early, and it has not got going yet.

(I am in the grip of commercial realities here)

If interested in writing in Rust an API that is exposed to the FFI as a C API, there is:

  • image

It is not (yet) tailored to perform FFI over a specific language higher level than C (so, if if you do want to interact with more advanced FFI features from Dart, you will need to use some of the dart-sys mentioned aboved), but it is tailored to write Rusty functions with minimal unsafe that nevertheless have a well-defined FFI ABI, at the cost of not necessarily being the most "idiomatic" one in C.

So, for instance, rather than a function taking a raw pointer and a raw len, you can write a function taking a c_slice::Ref<'_, u8> (which can safely be casted from and to &'_ [u8]), which will be translated to a function taking a:

typedef struct {
    /** \brief
     *  Pointer to the first element (if any).
     */
    uint8_t const * ptr;

    /** \brief
     *  Element count
     */
    size_t len;

} slice_ref_uint8_t;

This makes it so if you do have a bit of control over the higher-level language glue code you write at the other end of the FFI boundary, you end up writing code that still looks idiomatic Rust (often with no unsafe at all) rather than an ugly mess of unsafe C-looking code.

1 Like

As far as I know initially you couldn't make flutter to use FFI, I don't remember details.

We currently using it for our commercial applicatilon.
There are two main problems with FFI:

  1. Amount of boilerplate you need for each function is enormous (we had to work it around by having few functions in Rust code and replacing it with basically our own JSON RPC on top of FFI method)
  2. Difficulty to keep Rust structures in sync with Dart structures (I had to write macro to automatically generate Dart code for our Rust structures in the end)

Other than that there should be no technical limitations (note that flutter debug build is slow)

Awesome folks.

There is a lot of information for me.

I can use this if the flutter project gets off the ground I will experiment with the FFI. Immature or not, on reflection, if it is adequate it will help a lot.

While returning to C++ has some merits for me I think we would benefit from Rust if we can make the FFI work.

I am optimistic.

Thanks for all your attention, it has been very useful

1 Like

Yes. It works well, even with async code and callbacks to/from. Google flutterust

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.