Mobile Development 15 min read

Master Dart FFI: Step‑by‑Step Guide to Call C/C++ from Flutter and Back

This tutorial walks you through using Dart's foreign function interface (FFI) in Flutter, showing how to create a macOS plugin project, generate bindings with ffigen, call native C/C++ functions, handle callbacks and asynchronous threads, and integrate message passing between Dart isolates and native code.

Alibaba Cloud Developer
Alibaba Cloud Developer
Alibaba Cloud Developer
Master Dart FFI: Step‑by‑Step Guide to Call C/C++ from Flutter and Back

What is FFI

FFI (Foreign Function Interface) is a mechanism that lets code written in one programming language call functions or services written in another language, similar to Java JNI.

Create a sample project

Generate a Flutter plugin project for macOS using the plugin_ffi template and run it to produce a macOS executable.

flutter --version
flutter create --template=plugin_ffi --platforms=macos plugin_ffi_sample
cd plugin_ffi_sample/example
flutter run

Inspect the plugin project

The example directory demonstrates how to use the plugin. The pubspec.yaml declares a path dependency on the plugin itself.

dependencies:
  flutter:
    sdk: flutter
  plugin_ffi_sample:
    path: ../

Calling native functions from Dart

Import the generated bindings and call sum and sumAsync from Dart.

import 'package:plugin_ffi_sample/plugin_ffi_sample.dart' as plugin_ffi_sample;

class _MyAppState extends State<MyApp> {
  late int sumResult;
  late Future<int> sumAsyncResult;

  @override
  void initState() {
    super.initState();
    sumResult = plugin_ffi_sample.sum(1, 2);
    sumAsyncResult = plugin_ffi_sample.sumAsync(3, 4);
  }
}

Generated binding file

The file plugin_ffi_sample_bindings_generated.dart is auto‑generated by ffigen and maps Dart calls to the native symbols.

// AUTO GENERATED FILE, DO NOT EDIT.
import 'dart:ffi' as ffi;

class PluginFfiSampleBindings {
  final ffi.Pointer<ffi.NativeFunction<ffi.Int32 Function(ffi.Int32, ffi.Int32)>> _sum;
  PluginFfiSampleBindings(ffi.DynamicLibrary dylib)
      : _sum = dylib.lookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Int32, ffi.Int32)>>('sum');

  int sum(int a, int b) => _sum.asFunction<int Function(int, int)>()(a, b);
}

Adding a C/C++ callback

Define a function pointer type pong and a ping function that invokes the callback.

typedef void (*pong)(void);
FFI_PLUGIN_EXPORT void ping(pong callback) {
  printf("ping
");
  callback();
}

Regenerate bindings after changing the header.

flutter pub run ffigen --config ffigen.yaml

Asynchronous thread callbacks

When using a C++ thread, wrap the callback with Dart_PostCObject_DL to send a message to a Dart SendPort instead of calling Dart code directly.

void entry_point(Dart_Port_DL port) {
  printf("entry_point
");
  Dart_CObject obj;
  obj.type = Dart_CObject_kString;
  obj.value.as_string = "pong";
  Dart_PostCObject_DL(port, &obj);
}

FFI_PLUGIN_EXPORT void ping(Dart_Port_DL port) {
  printf("ping
");
  std::thread* t = new std::thread(entry_point, port);
}

Integrating with Flutter

In Dart, create a ReceivePort to listen for messages from native code and pass its nativePort to ping. Also initialize the dynamically linked Dart API.

void initializeApiDL() => _bindings.ffi_Dart_InitializeApiDL(NativeApi.initializeApiDLData);

void ping() {
  final receivePort = ReceivePort()..listen((msg) => print('pong $msg'));
  _bindings.ping(receivePort.sendPort.nativePort);
}

@override
void initState() {
  super.initState();
  initializeApiDL();
  ping();
  sumResult = plugin_ffi_sample.sum(1, 2);
  sumAsyncResult = plugin_ffi_sample.sumAsync(3, 4);
}

Key take‑aways

Use toNativeUtf8 with an allocator and free the memory after the call. NativeFinalizer can bind Dart objects to C++ objects and run cleanup code when the Dart object is garbage‑collected.

By following these steps you can successfully call C/C++ code from Dart, handle synchronous and asynchronous callbacks, and communicate between native threads and Dart isolates.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DARTFlutterMobile DevelopmentFFICInterop
Alibaba Cloud Developer
Written by

Alibaba Cloud Developer

Alibaba's official tech channel, featuring all of its technology innovations.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.