Git Product home page Git Product logo

flutter-go-bridge's Introduction

flutter-go-bridge

Reuse existing Go libraries in Flutter by calling Go from Dart using auto generated bindings.

Features

  • MacOS, iOS, Windows, Linux and Android support.
  • Sync and Async calls from Dart.
  • Passing primitives (various int's), string's and nested structures.
  • Automatic error to Exception mapping.
  • Basic object passing.

Getting Started

  1. Install fgb

    go get -u github.com/csnewman/flutter-go-bridge
    
  2. Create a wrapper around your Go code.

  3. Generate bindings

    • Run go generate in the directory containing your wrapper.
  4. Use the generated bindings from your Flutter/Dart application

  5. Automate library building by integrating into flutter build.

  6. When modifying the Go code, you may need to call flutter clean to trigger a rebuild, dependent upon your Go source location and configured source directories.

Go wrapper

The bridge does not support all Go constructs and instead relies on a subset. This allows for a more ergonomic wrapper.

Therefore, you should create a Go package containing a wrapper around more complex Go libraries. The generator will scan this package and generate a bridge package containing the necessary FFI bridging logic.

See example for a complete example.

The process is as follows:

  1. mkdir go (inside the Flutter project)
  2. Create go/example.go, containing the following:
     //go:generate go run github.com/csnewman/flutter-go-bridge/cmd/flutter-go-bridge generate --src example.go --go bridge/bridge.gen.go --dart ../lib/bridge.gen.dart
     package example
    Replace the --dart path, with a suitable location inside your flutter applications lib directory.
  3. Write a simplified wrapper, using the template mappings below.
  4. Invoke go generate to automatically regenerate the bridge.gen.go and the corresponding bridge.gen.dart file.

Dart setup

From Dart:

  1. Import generated bridge
    import 'bridge.gen.dart';
  2. Load library
    var bridge = Bridge.open();
  3. Invoke functions
    bridge.example();
    await bridge.exampleAsync();

Mappings

The following patterns are supported:

Function calls

func Simple(a int, b int) int {
    return a + b
}

Will produce:

int simple(int a, int b);

Future<int> simpleAsync(int a, int b);

Function calls, with errors

func SimpleError(a int, b int) (int, error) {
    return 0, errors.New("an example")
}

Will produce:

int simpleError(int a, int b);

Future<int> simpleErrorAsync(int a, int b);

If the Go function returns an error, the simpleError function will throw a BridgeException.

Struct passing

type ExampleStruct struct {
    A int
    B string
}

func StructPassing(val ExampleStruct) {
}

Will produce:

final class ExampleStruct {
    int a;
    String b;

    ExampleStruct(this.a, this.b);
}

and

void structPassing(ExampleStruct val);

Future<void> structPassingAsync(ExampleStruct val);

Structs passed in this manner will be passed by value, meaning the contents will be copied.

Value structs can not contain private fields.

Objects

TODO: Document

Platform building

The platforms supported by flutter use various build tooling, which complicates integrating Go into the build pipeline. Originally this project had hooks into the build systems for Windows, Linux and Android, however this had high maintenance and was not trivial to integrate into the Mac ecosystem.

Flutter (& Dart) currently have an experimental feature called Native Assets which greatly simplifies the setup. This does however mean that for now, this project requires using the flutter master channel.

Native Assets approach

A complete example can be seen in the exampleapp folder.

  1. Switch to the master flutter channel
    flutter channel master
  2. Enable the Native Assets experiment
    flutter config --enable-native-assets
  3. Add the required dependencies to pubspec.yaml
    logging: ^1.2.0
    native_assets_cli: ^0.5.4
    native_toolchain_go: ^0.3.0
    ffi: ^2.1.2
  4. Fetch dependencies
    flutter pub get
  5. Create a build.dart file
    import 'package:native_toolchain_go/go_native_toolchain.dart';
    import 'package:logging/logging.dart';
    import 'package:native_assets_cli/native_assets_cli.dart';
    
    void main(List<String> args) async {
      await build(args, (config, output) async {
        final packageName = config.packageName;
    
        final goBuilder = GoBuilder(
          name: packageName,
          assetName: 'bridge.gen.dart',
          bridgePath: 'go/bridge',
          sources: ['go/'],
          dartBuildFiles: ['hook/build.dart'],
        );
       
        await goBuilder.run(
          buildConfig: config,
          buildOutput: output,
          logger: Logger('')
            ..level = Level.ALL
            ..onRecord.listen((record) => print(record.message)),
        );
      });
    }
    The assetId path needs to match the location of the autogenerated bridge.gen.dart file, as flutter uses this internally to automate library resolution. You may need to specify a list of source directories to the GoBuilder to allow automatic rebuilding as necessary.

You should now be able to use your IDE and other tooling as usual.

Manual building

If you do not want to use the master channel or wish to customise the build process, you can manually build the Go library and bundle with your application as necessary:

CGO_ENABLED=1 go build -buildmode=c-shared -o libexample.so example/bridge/bridge.gen.go

You can specify GOOS and GOARCH as necessary.

flutter-go-bridge's People

Contributors

csnewman avatar

Stargazers

clutchJoe avatar 陈哈哈 avatar vacancylee avatar H avatar PT avatar Ma3X avatar Moustapha Kodjo Amadou avatar  avatar  avatar Frost Lotus avatar  avatar  avatar  avatar Buck avatar rere avatar oskar avatar  avatar  avatar Kuba Raczkowski avatar yangjun avatar Burak Karahan avatar Liloupar avatar  avatar  avatar Gjergji Ramku avatar Andrew McElroy avatar  avatar colin avatar Brad Pillow avatar

Watchers

 avatar  avatar Moustapha Kodjo Amadou avatar

flutter-go-bridge's Issues

Use with pure Dart packages

Hello!

Is there a plan to make this generator work with pure Dart packages? I can pin this package to a commit before the switch to the native toolchain, but I'll miss any improvements.

If not, no problem. Its probably called flutter go bridge for a reason.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.