Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ykmnkmi/06e0f515266d77c88b71f5eb9e6e21ac to your computer and use it in GitHub Desktop.
Save ykmnkmi/06e0f515266d77c88b71f5eb9e6e21ac to your computer and use it in GitHub Desktop.
Async messaging between Flutter and C++ using Dart ffi NativePort

C++

  • Copy Dart SDK (${FLUTTER_DIR}/bin/cache/dart-sdk/include) to your project, e.g. ios/Classes/
  • Add your own code like the following fragment
#include "dart_api_dl.h"

// Receives NativePort ID from Flutter code
static Dart_Port_DL dart_port = 0;

// Ensure that the function is not-mangled; exported as a pure C function
extern "C" void set_dart_port(Dart_Port_DL port)
{
    dart_port = port;
}

// Sample usage of Dart_PostCObject_DL to post message to Flutter side
void debug_print(const char *message)
{
    if (!dart_port)
        return;
    Dart_CObject msg;
    msg.type = Dart_CObject_kString;
    msg.value.as_string = (char *)message;
    // The function is thread-safe; you can call it anywhere on your C++ code
    Dart_PostCObject_DL(dart_port, &msg);
}

Flutter

import 'package:ffi/ffi.dart';

class FfiNativePort {
  // libffi_native_port.so is the shared module generated by the C++ code above
  static final module =
      Platform.isAndroid ? DynamicLibrary.open("libffi_native_port.so") : DynamicLibrary.process();

  // Dart_InitializeApiDL defined in Dart SDK (implemented in dart_api_dl.c)
  static final Dart_InitializeApiDLFunc _Dart_InitializeApiDL =
      module.lookup<NativeFunction<Dart_InitializeApiDLFunc>>("Dart_InitializeApiDL").asFunction();

  // The set_dart_port function defined on the C++ code above
  static final _SetDartPortFunc _setDartPort =
      module.lookup<NativeFunction<Void Function(Int64)>>("set_dart_port").asFunction();

  static Pointer<Void>? cookie;

  // initialization
  static void initialize() {
    if (cookie != null) {
      return;
    }

    // Call Dart_InitializeApiDL with NativeApi.initializeApiDLData
    cookie = _Dart_InitializeApiDL(NativeApi.initializeApiDLData);

     final pub = ReceivePort()
      ..listen((message) {
        // TODO: processing messages from C++ code
      });

    // Pass NativePort value (int) to C++ code
    _setDartPort(pub.sendPort.nativePort);
  }
}

Reference(s)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment