Dart
FFI
Write native integration with dart:ffi.
FFI
dart:ffi lets Dart code call C-based native libraries. A DynamicLibrary is loaded, lookupFunction finds a symbol, and typedefs pair Dart and native signatures.
Two typedefs: NativeAdd = Int32 Function(Int32, Int32) (native signature) and DartAdd = int Function(int, int) (Dart signature). lookupFunction<NativeAdd, DartAdd>('native_add') bridges them.
In this lesson we define NativeMathService implements MathService. The add method wraps the native call; describe returns the binding name. A real native call needs a .so/.dll; here we write a simulated implementation.
Native and Dart signatures
In FFI each native function needs two typedefs: the native side uses types like Int32, Pointer; the Dart side uses int, double.
Example: typedef NativeAdd = Int32 Function(Int32 a, Int32 b); and typedef DartAdd = int Function(int a, int b);. lookupFunction<NativeAdd, DartAdd> pairs them.
In this lesson we write add as a simulated a + b. In a real project this would call the function returned by lookupFunction. The contract stays the same.
Exercise Add NativeMathService
The MathService is already defined below. Now add import 'dart:ffi';. Define typedef NativeAdd = Int32 Function(Int32 a, Int32 b); and typedef DartAdd = int Function(int a, int b);. Define class NativeMathService implements MathService with final String bindingName; NativeMathService(this.bindingName); @override int add(int a, int b) => a + b; String describe() => 'native: $bindingName';. In main create final svc = NativeMathService('native_add');; add print(svc.describe()); and print('result: ${svc.add(2, 3)}');.
Show example solution
import 'dart:ffi';
abstract class MathService {
int add(int a, int b);
}
typedef NativeAdd = Int32 Function(Int32 a, Int32 b);
typedef DartAdd = int Function(int a, int b);
class NativeMathService implements MathService {
final String bindingName;
NativeMathService(this.bindingName);
@override
int add(int a, int b) => a + b;
String describe() => 'native: $bindingName';
}
void main() {
print('service ready');
final svc = NativeMathService('native_add');
print(svc.describe());
print('result: ${svc.add(2, 3)}');
}
Test yourself
-
Implementing the interface
class NativeMathService ____ MathService { }
Show answer
class NativeMathService implements MathService { }
-
What can you do with dart:ffi?
- Calling native C functions
- JSON serialization
- HTTP requests
- File reading
Show answer
Calling native C functions — dart:ffi calls native C functions.
-
Match the FFI parts
- dart:ffi
- Native interop
- DynamicLibrary
- Library loader
- lookupFunction
- Symbol lookup
- Int32
- Native integer
Next lesson: Codegen