---
id: wiki-2026-0508-dart-ffi-foreign-function-interface
title: Dart FFI (Foreign Function Interface)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [dart:ffi, native interop]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [dart, flutter, ffi, native, c-interop]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
  language: dart
  framework: flutter
---

# Dart FFI (Foreign Function Interface)

## 매 한 줄
> **"매 Dart ↔ C/C++ 의 zero-overhead direct call — `dart:ffi`"**. 매 Flutter 3.x 부터 stable + `ffigen` 의 자동 binding 생성. 매 native lib (SQLite, OpenCV, Rust crate) 의 직접 호출 — 매 platform channel 의 async overhead 우회.

## 매 핵심

### 매 FFI 의 작동 원리
- 매 `DynamicLibrary.open()` 의 .so/.dylib/.dll load.
- 매 C ABI signature 의 Dart `Native<T>` typedef mapping.
- 매 sync call — 매 Dart isolate 와 동일 thread 에서 즉시 실행.
- 매 Pointer<T> 의 manual memory management.

### 매 vs Platform Channel
| 축 | FFI | Platform Channel |
|---|---|---|
| latency | μs | ms |
| sync | yes | no (async) |
| target | C/C++/Rust | Java/Kotlin/Swift |
| async-safe | 매 isolate | yes |

### 매 ffigen workflow
- 매 C header (`.h`) → ffigen → Dart binding 자동 생성.
- 매 manual typedef 작성 의 elimination.

## 💻 패턴

### Basic FFI call
```dart
// hello.dart
import 'dart:ffi';
import 'dart:io' show Platform;
import 'package:ffi/ffi.dart';

typedef CAdd = Int32 Function(Int32, Int32);
typedef DartAdd = int Function(int, int);

final lib = DynamicLibrary.open(
  Platform.isMacOS ? 'libmath.dylib' : 'libmath.so',
);
final add = lib.lookupFunction<CAdd, DartAdd>('add');

void main() {
  print(add(2, 3)); // 5
}
```

### Native annotation (Dart 3.3+)
```dart
import 'dart:ffi';

@Native<Int32 Function(Int32, Int32)>(symbol: 'add', isLeaf: true)
external int add(int a, int b);

void main() => print(add(2, 3));
```

### String marshalling
```dart
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef CGreet = Pointer<Utf8> Function(Pointer<Utf8>);
typedef DartGreet = Pointer<Utf8> Function(Pointer<Utf8>);

final greet = lib.lookupFunction<CGreet, DartGreet>('greet');

final namePtr = 'Yuna'.toNativeUtf8();
final resultPtr = greet(namePtr);
final result = resultPtr.toDartString();
calloc.free(namePtr); // 매 manual free 의 필수
print(result);
```

### Struct passing
```dart
final class Point extends Struct {
  @Double() external double x;
  @Double() external double y;
}

typedef CDistance = Double Function(Pointer<Point>, Pointer<Point>);
typedef DartDistance = double Function(Pointer<Point>, Pointer<Point>);

final dist = lib.lookupFunction<CDistance, DartDistance>('distance');
final a = calloc<Point>()..ref.x = 0..ref.y = 0;
final b = calloc<Point>()..ref.x = 3..ref.y = 4;
print(dist(a, b)); // 5.0
calloc.free(a); calloc.free(b);
```

### ffigen 의 사용
```yaml
# pubspec.yaml
dev_dependencies:
  ffigen: ^14.0.0

# ffigen.yaml
name: NativeMath
description: Bindings for libmath
output: lib/src/math_bindings.dart
headers:
  entry-points: ['native/math.h']
```

```bash
dart run ffigen --config ffigen.yaml
```

### Async FFI (NativePort)
```dart
// 매 long-running C work 의 main isolate block 회피
import 'dart:ffi';
import 'dart:isolate';

final port = ReceivePort();
final nativePort = port.sendPort.nativePort;

// C 측 에서 Dart_PostCObject_DL(nativePort, ...) 의 post
port.listen((msg) => print('from native: $msg'));
```

## 매 결정 기준

| 상황 | Approach |
|---|---|
| 매 sync μs-latency native call | FFI |
| 매 platform-specific iOS/Android API | Platform Channel |
| 매 large C/C++ codebase reuse | FFI + ffigen |
| 매 Rust integration | FFI + flutter_rust_bridge |
| 매 simple 1-shot file/permission | Pigeon plugin |

**기본값**: 매 native lib 의 binding → ffigen, 매 OS API 호출 → Pigeon/MethodChannel.

## 🔗 Graph
- 부모: [[Flutter]] · [[Dart]]
- 변형: [[Flutter_AOT_Compilation_Dart]]
- 응용: [[Flutter_Impeller]] · [[Skia]]
- Adjacent: [[WebAssembly]] · [[JSI (JavaScript Interface)]]

## 🤖 LLM 활용
**언제**: 매 Flutter 의 native lib (sqlite, ffmpeg, opencv, ort) 통합, 매 Rust crate 의 mobile 노출, 매 perf-critical CPU work 의 offload.
**언제 X**: 매 simple JSON-style platform API — 매 Pigeon 의 권장.

## ❌ 안티패턴
- **매 free 누락**: 매 calloc 후 free X — 매 native heap leak.
- **매 leaf 미표시**: 매 isLeaf=true 누락 — 매 GC safepoint overhead.
- **매 isolate 안전 무시**: 매 long C call 의 main isolate block.
- **매 manual binding**: 매 ffigen 의 skip — 매 type drift 의 발생.

## 🧪 검증 / 중복
- Verified (dart.dev/guides/libraries/c-interop, Dart 3.3 release 2024-02, ffigen 14 docs).
- 신뢰도 A.

## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — FFI 의 sync interop, ffigen workflow 정리 |
