Dart FFI: Calling C Code from Dart
Dart FFI is a bridge to the C world, letting you call native C libraries directly from Dart. Use it to access OS APIs or high-performance C/C++ code. The footgun: you must manually manage native memory, risking crashes or leaks if you forget to free.
Why it exists
Dart runs in its own managed environment with automatic memory management. However, most operating systems and countless high-performance libraries are written in C. FFI was created to bridge this gap, allowing Dart code to leverage this vast ecosystem of native code without rewriting everything from scratch.
The mental model
Think of Dart FFI as a translation layer or an adapter plug. Your Dart code speaks Dart, and a C library speaks C. FFI lets you define a contract in Dart—the function signature—that matches a function in the C library. It then handles the low-level details of calling that C function and marshalling data back and forth across the language boundary.
How it works
The process involves three main steps. First, you load a native dynamic library (like a .so, .dll, or .dylib) into your Dart application. Second, you look up a specific function symbol within that library by its name. Third, you cast that symbol to a Dart function signature using dart:ffi types like Pointer, Int32, or Void. This gives you a callable Dart function that executes the underlying C code.
When to use it
Use FFI when you need to interface with platform-specific native APIs (e.g., Win32 on Windows), integrate a high-performance C/C++ library for tasks like scientific computing or game physics, or reuse a critical piece of existing C code in a new Dart or Flutter application. The ffigen tool can automate generating the Dart bindings from C header files.
When not to use it
Avoid FFI for simple logic that can be easily written in pure Dart. The overhead of managing memory and type conversions makes it unsuitable for trivial tasks. It is also not available for web applications, which run in a browser sandbox and require JS interop instead.
One canonical example
A common use is calling a simple C function. Imagine a C library with int32_t sum(int32_t a, int32_t b);. In Dart, you would load the library, look up the sum function, and define its type: final sum = dylib.lookup<NativeFunction<Int32 Function(Int32, Int32)>>('sum').asFunction<int Function(int, int)>();. Now you can call sum(2, 3) in Dart, and it will execute the native C code, returning 5.
Interview question
What is a primary risk or challenge when using Dart FFI to call native C code?
- a.Manually managing memory allocated by C functions to prevent leaks or crashes.Correct
- b.Significant performance overhead making it unsuitable for high-performance tasks.
- c.Automatic type conversions between Dart and C leading to unexpected data loss.
- d.The inability to reuse existing C libraries without recompilation.
Why? this is the answer
The card explicitly warns that "you must manually manage native memory, risking crashes or leaks if you forget to free," identifying this as a significant "footgun." Distractor A is incorrect because FFI is specifically recommended for integrating "high-performance C/C++ libraries."
Just read this? Test yourself on what you have been reading.
Read the original → dart.dev
- #dart
- #ffi
- #native
- #interop
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on dart — each one lists the topics its interview covers.
See open roles