0PricingLogin
Flutter Mobile Development · Lesson

Calling C Libraries with dart:ffi

Bind to native shared libraries and marshal structs and pointers through dart:ffi.

Why dart:ffi?

dart:ffi is Dart's Foreign Function Interface. It lets your Flutter app call functions in native C shared libraries (.so, .dylib, .dll, or the iOS process image) directly, with no platform-channel round-trip.

  • Synchronous by default and very low overhead, unlike MethodChannel which serializes messages across an async boundary.
  • Ideal for CPU-heavy code, existing C/C++/Rust libraries, and OS-level APIs (sqlite, libsodium, image codecs).
  • You bind a C signature to a Dart signature, then call it like an ordinary function.

The cost: you manage memory and types yourself. Get a pointer or a struct layout wrong and you crash the whole process.

Opening a DynamicLibrary

Everything starts with a DynamicLibrary. It is the handle to the loaded native code from which you look up symbols.

  • DynamicLibrary.open(path) loads a shared library by file name. On Android use 'libfoo.so'; on iOS/macOS code is usually statically linked, so use DynamicLibrary.process() or DynamicLibrary.executable().
  • Pick the right name per platform with Platform.isAndroid / Platform.isIOS.
import 'dart:ffi';
import 'dart:io' show Platform;

DynamicLibrary openNativeLib() {
  if (Platform.isAndroid) {
    return DynamicLibrary.open('libnative_math.so');
  }
  if (Platform.isIOS || Platform.isMacOS) {
    // Symbols are linked into the app process on iOS.
    return DynamicLibrary.process();
  }
  if (Platform.isWindows) {
    return DynamicLibrary.open('native_math.dll');
  }
  return DynamicLibrary.open('libnative_math.so');
}

All lessons in this course

  1. Calling C Libraries with dart:ffi
  2. Type-Safe Platform Channels with Pigeon
  3. Writing Custom Platform Plugins for iOS and Android
  4. Background Isolates and Native Memory Management
← Back to Flutter Mobile Development