Skip to content

Look into use the new Dart / Flutter FFI under development #58

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ghost opened this issue Jan 4, 2019 · 18 comments
Closed

Look into use the new Dart / Flutter FFI under development #58

ghost opened this issue Jan 4, 2019 · 18 comments
Labels
embedder Issue concerns the embedder package engine Depends on support form the Flutter Engine enhancement New feature or request wontfix This will not be worked on

Comments

@ghost
Copy link

ghost commented Jan 4, 2019

flutter/flutter#7053

  • follow the link at the bottom and down the rabbit hole.

Basically it will mean you can take your golang code and compile it to a shared lib for Mobile and Desktop.


CC="${NDK_DIR}/bin/arm-linux-androideabi-gcc" \
CXX="${NDK_DIR}/bin/arm-linux-androideabi-g++" \
CGO_ENABLED=1 CGO_CFLAGS="-march=armv7-a" \
GOOS=android GOARCH=arm GOARM=7 \
go build -i -buildmode=c-shared -o libgomain.so

Why its a feasible approach:

  1. speed.
  2. agnostic. The same code for Desktop and Mobile can be plugged into Flutter in the exact same way.

when ?
Q1 2019 they say.

@pchampio
Copy link
Member

pchampio commented Jan 12, 2019

I'll keep this issue open as a reminder.

@ghost
Copy link
Author

ghost commented Jan 21, 2019

i think that its a long way of btw. But still keep in mind long term i guess.
Pity they did not just use Protobufs i feed since so many language support it.
Maybe worth thinking about for Plugin architecture maybe

@davidmartos96
Copy link
Contributor

They recently released an alpha preview for developers to test.

dart-lang/sdk#34452 (comment)

@ghost
Copy link
Author

ghost commented May 29, 2019

Flutter Dart FFI has now landed in Master

This means you can write Flutter Plugins in golang, and compile them as a shard lib as c.
So you have none of the speed / Perf issues on Mobile. I noticed that in the last few days Android studio has NDK side by side support also.
On Desktop, you can hook in easily with the exact same shared lib cross compiled.
On Embedded, you can use Flutter and golang.
On Flutter Web, you can compile to WASM to provide a plugin, however this has not been stated by the team, but it is the likely technical roadmap IHMO.

The opportunity is that go-flutter can be the go to place for golang programmers that want to use Flutter, and by embracing the Official Flutter Desktop using FFI we have no performance issues.
We still have the best of both worlds on Desktop in that you code your plugin once and it runs on all Desktops.
Hover and that tooling can maybe transition to allow using both the GO-Flutter and the Flutter Desktop ways of doing things.

But in the end the FFI means no speed slow downs and Same code for plugins everywhere, so its going to be the way forward.

I think there are a few good libraries around to make it easy to take a golang lib and generate the golang code with the "import c" and the header lib. Gotta do some more research.
But we could use that in go-flutter to make it easy for golang programmers to keep using go-flutter since they are interested in FLutter with golang.

I hope that this is welcomed and not seen as undermining the efforts here.
Go-flutter helped me alot and Its still early days for FFI and there will be breakages with FFI still.
But we could start down this road now if we wanted to.

LINKS:

Official Example: https://github.com/dart-lang/sdk/blob/master/samples/ffi/sqlite/README.md

Use golang shared libs with Dart FFI and flutter-desktop.
Watching: https://github.com/dart-lang/sdk/projects/13

Watching: https://github.com/asyncapi/parser/blob/master/cparser/cparser.go

  • For go embedded with FLutter

FFI Forum:
https://groups.google.com/forum/#!topic/dart-ffi/eYuAHy-zoC4

Mongo DB Realm using Dart FFI
https://github.com/nhachicha/realm-dart-ffi

This would mean we can use Google Official Flutter Desktop, because the Desktop Plugins API can hook into the golang shared lib.

Example of many languages hooking into golang shared lib.
https://github.com/vladimirvivien/go-cshared-examples

@pchampio
Copy link
Member

pchampio commented May 29, 2019

FFI looks very promising.

Sadly I don't have the time to take an in-depth look into it now.
I'm focusing on bug-fixes and standardization with the FDE at the moment.

If @gedw99 or anyone else is interested in FFI, please submit a PR, @GeertJohan, and I will be happy to review it!

@pchampio pchampio assigned ghost May 29, 2019
@pchampio pchampio added embedder Issue concerns the embedder package engine Depends on support form the Flutter Engine enhancement New feature or request labels May 29, 2019
@go-flutter-desktop go-flutter-desktop deleted a comment Jul 23, 2019
@pchampio pchampio added the wontfix This will not be worked on label Jul 23, 2019
@provokateurin
Copy link
Member

provokateurin commented Aug 3, 2019

At first I want to say I'm new to go-flutter, but I know that the project exists for some time.
I'm very used to the "official" desktop embedder, but as I was exploring the project I saw that it implements much more than the "official" embedder. That's why I'm so interested in it.

If I understood it correctly it should be possible to compile the go plugins to shared libraries and use them using the new dart FFI? Then it would be possible to use them even with the "official" embedder right?

I'm not sure why we need to compile the plugins for mobile, because almost all plugins are only for mobile yet and this project has the focus on desktop and it's plugins extend the existing plugins for mobile to desktop.

@pchampio
Copy link
Member

pchampio commented Aug 3, 2019

@jld3103 as my last comment said, I have no idea how dart FFI works.
My basic understanding is that the dart plugins can be made from native C source code through a binding layer.

If I understood it correctly it should be possible to compile the go plugins to shared libraries and use them using the new dart FFI?

Yes I thinks it's right, but at the moment only C/C++ integration is possible. Just to clarify, plugin made to work on dart:ffi aren't the same as flutter plugin, dart:ffi plugin by pass the flutter layer and talk directly to the dart-runtime.

Then it would be possible to use them even with the "official" embedder right?

Not sure if it's possible, but yes, from my understanding the dart:ffi has nothing to do with the flutter framework.

I'm repeating myself, but, I have absolutely no plan to work on dart:ffi support for go-flutter, it's too young at the moment.

@provokateurin
Copy link
Member

Some examples: https://github.com/mjohnsullivan/ffi

@pchampio
Copy link
Member

pchampio commented Sep 11, 2019

First, from the following Cpp code:

// filename: hello_world.cpp
#include<iostream>
#include<stdio.h>

extern "C" {
   void helloWorld() {
      std::cout<<"Hello World !"<<std::endl;
   }
}

I've compiled it:

# mac (.dylib)
g++ -dynamiclib -o ./libHelloWorld.dylib ./hello_world.cpp

# Linux (.so)  if Android, have to compile for arm64 or arm
g++ -shared  -fPIC -o ./libHelloWorld.so ./hello_world.cpp

# windows (.dll) (using TDM-GCC-64, GCC 5.1.0)
g++ -shared -o HelloWorld.dll .\hello_world.cpp

Secondly I've thrown the .dll | .so | .dylib into the go/assets directory.

Lastly using the following main_desktop.dart file

import 'package:flutter/foundation.dart'
    show debugDefaultTargetPlatformOverride;
import 'package:flutter/material.dart';

import "dart:ffi" as ffi;
import 'dart:io' show Platform;
import "package:path/path.dart" show join;
import 'dart:io';

ffi.DynamicLibrary _dlopenPlatformSpecific(String name, {String path}) {
  String fullPath = _platformPath(name, path: path);
  return ffi.DynamicLibrary.open(fullPath);
}

String _platformPath(String name, {String path = ''}) {
  if (Platform.isMacOS) return path + "lib" + name + ".dylib";
  if (Platform.isLinux || Platform.isAndroid)
    return path + "lib" + name + ".so";
  if (Platform.isWindows) return path + name + ".dll";
  throw Exception("Platform not implemented");
}

void main() {
  final libHelloWorld = _dlopenPlatformSpecific('HelloWorld',
      path: join(
        Directory(Platform.resolvedExecutable).parent.path,
        'assets/',
      ));
  final helloWorld = libHelloWorld
      .lookupFunction<ffi.Void Function(), void Function()>("helloWorld");
  helloWorld();

  debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
  runApp(MaterialApp(home: Scaffold(body: Text("FFI!"))));
}

I call the shared lib from a flutter app (hover run) and get in the terminal output:

Hello World !

Putting the shared lib into the into the go/build/intermediates/linux (or darwin/windows) directory allows it to be persistent across hover run, the shared lib will be placed into go/build/outputs/linux/ by the hover tool-chain.

The path to the shared lib in dart Directory(Platform.resolvedExecutable).parent.path correspond to the generated assets directory.

@joeblew99

This comment has been minimized.

@joeblew99

This comment has been minimized.

@pchampio pchampio self-assigned this Nov 5, 2019
@pchampio pchampio removed the wontfix This will not be worked on label Nov 5, 2019
@pchampio pchampio removed their assignment Nov 5, 2019
@pchampio pchampio added the wontfix This will not be worked on label Nov 5, 2019
@davidmartos96
Copy link
Contributor

davidmartos96 commented Apr 28, 2020

Putting the shared lib into the into the go/assets directory allows it to be persistent across hover run, the shared lib will be placed into go/build/outputs/linux/assets by the hover tool-chain.

@pchampio Your setup works fine for including dynamic libraries intended to be used with FFI. But, is there any way to include assets splitted by the platform? In your solution, .so, .dll, and .dylib will all be bundled with all platforms. Any workaround for that?

@provokateurin
Copy link
Member

If you are using a go-flutter plugin you can put the compiled library in the dlib folder (symlinks also work). Then run hover plugins get (you have to do it every time you update the compiled library) to copy the libraries to your project. Then on every run/build the library is copied from the project to the output folder so only the one for the platform you are building for/running on is copied to the output.

@provokateurin
Copy link
Member

@pchampio maybe we should add an example for that? I already created such an project with ffi and would only need to modify minor things

@pchampio
Copy link
Member

pchampio commented Apr 28, 2020

@davidmartos96 The project go/build/intermediates/$OS folder has this purpose!

@jld3103 I'm still not fixed with how the plugin dlib folder work.
Sure, you can create a demo, it might no be necessary to go as far as building a plugin.
I'm sure a example with a Makefile would be fine.

@davidmartos96
Copy link
Contributor

davidmartos96 commented Apr 28, 2020

@jld3103 Thanks for the response! Yes I tried using a plugin, but with my current project setup I think it won't work. I am placing custom plugins in a folder called go-plugins at the root of the git repo, so when fetching such local plugin with the dynamic libraries, it fails because it tries to fetch it from remote. Maybe that is a bug in the hover plugins get flow?
Also, wouldn't the need of calling every time plugins get be a bit error prone?

@pchampio Does that mean I can include the intermediates folder in my git repo? Or should it be ignored?

@pchampio
Copy link
Member

@jld3103 I'm still not fixed with how the plugin dlib folder work. #311

@davidmartos96 yep, go/build/intermediates/$OS is what you are looking for.

@pchampio
Copy link
Member

pchampio commented Nov 1, 2020

Please check #498
For a golang FFI example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
embedder Issue concerns the embedder package engine Depends on support form the Flutter Engine enhancement New feature or request wontfix This will not be worked on
Development

No branches or pull requests

4 participants