К основному содержанию
скилл Claude Code CX Codex Cursor GitHub Copilot

dart-use-ffigen — скилл для Claude Code: автогенерация FFI-биндингов

Скилл учит агента генерировать FFI-биндинги через package:ffigen вместо ручного написания. Используй, когда нужно создать или расширить привязки к C/Objective-C/Swift библиотекам.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add flutter/agent-plugins --skill dart-use-ffigen -a claude-code
Открыть на GitHub

Что делает dart-use-ffigen

dart-use-ffigen направляет агента использовать FfiGenerator для автоматизации создания биндингов к нативному коду. Вместо того чтобы вручную писать DynamicLibrary.lookup, @Native функции и классы структур, скилл подсказывает генерировать их из заголовочных файлов.

Внутри скилла — пошаговая схема: проверка зависимостей в pubspec.yaml, создание генератора в tool/ffigen.dart, запуск dart run tool/ffigen.dart, верификация результата через dart analyze. Скилл требует, чтобы заголовочные файлы лежали в third_party/ или src/, а сгенерированные биндинги — в lib/src/third_party/ с расширением .g.dart. Обязателен пreamble с лицензией и предупреждением о генерации.

Если пакет использует нативные ассеты через native hooks, скилл советует включить recordUse: (_) => true для tree shaking и задать recordUseMapping при выводе.

Какие задачи решает

  • генерировать FFI-биндинги к C/Objective-C/Swift библиотекам автоматически
  • избежать ошибок ручного написания биндингов и struct-классов
  • расширить существующие нативные интеграции через фильтры включения
  • настроить tree shaking для нативных символов в продакшене
  • локализовать заголовочные файлы и генерированные биндинги по стандартам

Примеры запросов агенту

  • Добавь скилл dart-use-ffigen и создай генератор для биндингов к sqlite3
  • Используй ffigen для автогенерации FFI-биндингов вместо ручного написания @Native функций
  • Помоги мне расширить C-интеграцию: сгенерируй новые биндинги с включением только нужных функций

Как установить dart-use-ffigen

1Через Skills CLI (Vercel)

npx skills add flutter/agent-plugins --skill dart-use-ffigen -a claude-code

2Вручную: положить файлы

~/.claude/skills/dart-use-ffigen/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/dart-use-ffigen/

Из того же набора14

Весь набор →
flutter-apply-architecture-best-practices flutter Скилл раскладывает Flutter-приложение по слоям UI, Logic и Data. Пригодится для нового проекта или рефакторинга кода. Claude Code CX Codex Cursor +1 43 000установок flutter-build-responsive-layout flutter Скилл обучает агента строить адаптивные интерфейсы Flutter под экраны телефонов и десктопов. Он задаёт правила работы с LayoutBuilder и MediaQuery. Claude Code CX Codex Cursor +1 42 300установок flutter-add-widget-test flutter Скилл помогает писать компонентные тесты Flutter с помощью WidgetTester. Проверяет, как виджет отображается и реагирует на касания, скролл и ввод текста. Claude Code CX Codex Cursor +1 39 000установок flutter-add-integration-test flutter Скилл настраивает интеграционные тесты во Flutter через пакет integration_test. Он переносит действия из MCP-сервера в готовые тестовые сценарии. Claude Code CX Codex Cursor +1 38 000установок flutter-setup-declarative-routing flutter Настраивает декларативную маршрутизацию Flutter через go_router: маршруты по URL, вложенную навигацию и глубокие ссылки для веба и мобильных платформ. Claude Code CX Codex Cursor +1 37 600установок flutter-implement-json-serialization flutter Скилл учит агента создавать Dart-модели с методами fromJson и toJson через библиотеку dart:convert. Пригодится при ручном разборе простых структур данных в Flutter. Claude Code CX Codex Cursor +1 37 200установок flutter-add-widget-preview flutter Скилл учит агента создавать интерактивные превью виджетов во Flutter через package:flutter/widget_previews.dart. Пригодится для изолированной вёрстки UI без сборки всего приложения. Claude Code CX Codex Cursor +1 36 600установок flutter-setup-localization flutter Скилл автоматизирует инициализацию поддержки многоязычности в Flutter-проекте. Добавляет зависимости, включает генерацию кода и создаёт конфиг для работы с .arb-файлами. Claude Code CX Codex Cursor +1 36 600установок

Похожие

python-pro https://github.com/Jeffallan Скилл для написания типобезопасного Python 3.11+ с полной аннотацией, async-кодом и тестами. Генерирует код с type hints, настраивает mypy в строгом режиме, пишет pytest-тесты с фиксчурами и мокингом. Claude Code CX Codex Cursor +1 8 800установок cli-anything HKUDS Строит Python-харнесс с Click-командами для любого GUI-приложения или репозитория. Генерирует REPL, тесты и документацию по методологии CLI-Anything. Claude Code CX Codex Cursor +1 2 100установок n8n-code-javascript czlonkowski Помогает писать и отлаживать JavaScript в нодах Code для n8n, выбирать правильный режим выполнения и заменять цепочки промежуточных узлов. Claude Code CX Codex Cursor +1 7 100установок dry-refactoring kucherenko Скилл автоматизирует рефакторинг копипастных дубликатов, которые находит jscpd. Предлагает стратегии извлечения функции, параметризации, модуля или класса и показывает, с каких файлов начать. Claude Code CX Codex Cursor +1 3 600установок angular-new-app Angular Team @ Google Скилл для быстрого создания нового Angular-приложения с помощью Angular CLI. Проверяет окружение, генерирует проект с нужными флагами и направляет разработку по лучшим практикам Angular. Claude Code CX Codex Cursor +1 19 200установок migrate-to-shoehorn Matt Pocock Переводит type assertions с as в тестах на функции из @total-typescript/shoehorn. Нужен для частичных объектов и намеренно неверных данных в проверках. Claude Code 475 388установок write-swift emilkowalski Скилл помогает писать, проверять и переносить код на Swift с учётом модели языка. Подойдёт, когда нужно разобраться с конкурентностью, ошибкой или циклом удержания объектов. Claude Code CX Codex Cursor +1 117 500установок megacave JuliusBrussee Переводит ответы ассистента на классический китайский язык (вэньянь) для экономии места на экране. Активируется командами /megacave или /caveman wenyan. Claude Code CX Codex Cursor +1 24 400установок

Вопросы о dart-use-ffigen

Как установить dart-use-ffigen в Claude Code?

Запусти npx skills add flutter/agent-plugins --skill dart-use-ffigen -a claude-code, затем npx skills add flutter/agent-plugins --skill dart-use-ffigen -a claude-code. Скилл будет доступен в ~/.claude/skills/dart-use-ffigen/SKILL.md.

Что делает dart-use-ffigen?

Скилл учит агента генерировать FFI-биндинги автоматически через package:ffigen вместо ручного написания. Это предотвращает ошибки, упрощает поддержку и стандартизирует структуру проекта.

Какие требования к структуре проекта?

Заголовочные файлы должны быть в third_party/ или src/ (в корне пакета). Генератор размещается в tool/ffigen.dart. Сгенерированные биндинги пишутся в lib/src/third_party/ с расширением .g.dart. Обязателен preamble с лицензией.

Исходный текст

SKILL.md · BSD-3-Clause
---
name: dart-use-ffigen
description: Guide agents to use `package:ffigen` to automatically generate FFI bindings instead of writing them manually. Use this skill when a task involves writing new FFI bindings, extending C/Objective-C/Swift integrations, or replacing hand-crafted `dart:ffi` setups.
metadata:
  model: models/gemini-3.1-pro-preview
  last_modified: Thu, 28 May 2026 07:21:07 GMT
---
# Generating FFI Bindings using package:ffigen

## Contents
- [Introduction](#introduction)
- [Constraints](#constraints)
- [FFIgen Overview](#ffigen-overview)
- [Step-by-Step Workflow](#step-by-step-workflow)
- [Concrete Example: Binding a C Library](#concrete-example-binding-a-c-library)
- [Verification Checklist](#verification-checklist)

## Introduction

Automate and standardize the generation of FFI bindings using `package:ffigen` (`FfiGenerator`). Writing FFI bindings by hand is error-prone, brittle, and highly discouraged.

## Constraints

*   **No Hand-Written FFI Bindings**: If native headers (`.h` files) exist or are generated by a build step, never write manual `DynamicLibrary.lookup`, `@Native` external functions, or raw struct classes. Always use `FfiGenerator` to generate them.
*   **Generator Location**: The generator script should be located at `tool/ffigen.dart` within the target package root.
*   **Header Location**: If the native header files are third-party, they should be located in `third_party/` within the target package (otherwise placing them in a `src/` directory at the package root is also acceptable). If the headers are not in one of these standard locations, notify the user that it would be cleaner to move the header files to the standard location (e.g., `third_party/`).
*   **Targeted Inclusion Filters**: Avoid importing an entire native library unless specifically needed. Always apply precise inclusion lists using positive matches to minimize the size and cognitive load of the generated code (e.g., using `Functions.includeSet` or filtering matches in `include` closures).
*   **Output Setup**: If the generated FFI bindings interface with a third-party library (or reference third-party headers), the generated files must always be placed under `lib/src/third_party/`. The primary generated FFI bindings file must strictly use the `.g.dart` extension (e.g. `sqlite3.g.dart`).
*   **Preamble & License Headers**: Always supply a premium `preamble` in the `Output` class to specify the license. This must match the native third-party library's license, explicitly include the copyright header of the target native header file, and contain an automatic generation warning (e.g. `// Generated by package:ffigen. Do not edit manually.`).
*   **No Unnecessary Commits of Stale Bindings**: Ensure you run the generator script and check if the generated files have changed *before* finishing your task. Always verify the package by running `dart analyze`.
*   **Record Usage and Tree Shaking**: If the package is integrated into standard runtime execution or compiles native assets via native hooks:
    *   Enable recorded usage on all functions by setting `recordUse: (_) => true` under `Functions`.
    *   Specify the `recordUseMapping` target in `Output` (which must strictly be a `.g.dart` file under `lib/src/third_party/`, e.g. `lib/src/third_party/sqlite3.record_use_mapping.g.dart`) to register bindings for symbol tree shaking.

## FFIgen Overview

To construct the programmatic generator, use the core configuration objects imported from `package:ffigen/ffigen.dart`:

### 1. `FfiGenerator`
The parent class that orchestrates the configuration, parsing, and code generation.
```dart
FfiGenerator({
  Headers headers = const Headers(),
  Enums enums = Enums.excludeAll,
  Functions functions = Functions.excludeAll,
  Globals globals = Globals.excludeAll,
  Integers integers = const Integers(),
  Macros macros = Macros.excludeAll,
  Structs structs = Structs.excludeAll,
  Typedefs typedefs = Typedefs.excludeAll,
  Unions unions = Unions.excludeAll,
  UnnamedEnums unnamedEnums = UnnamedEnums.excludeAll,
  ObjectiveC? objectiveC,
  required Output output,
}).generate();
```

### 2. `Headers`
Configures Clang header parsing targets and compiler flags.
*   `entryPoints`: A list of target header `Uri` inputs.
*   `include`: A filter function `bool Function(Uri header)` that handles transitive header imports.
*   `compilerOptions`: Custom preprocessor/include compiler flags to pass directly to libclang.
*   `ignoreSourceErrors`: Set to `true` to silence errors occurring inside third-party headers during parsing.

### 3. `Functions`
Specifies which native C/C++ functions to expose in Dart.
*   `include`: A matcher function (e.g. `(decl) => {'my_func'}.contains(decl.originalName)` or `Functions.includeSet({'my_func'})`).
*   `isLeaf`: Declares functions as leaf functions (`(decl) => true`) if they do not call back into Dart or block thread execution.
*   `recordUse`: Enables metadata generation for native asset tree shaking (essential in `dart-lang/native`). Set to `(_) => true`.

### 4. `Output`
Configures target generated files.
*   `dartFile`: Target `Uri` where the primary FFI bindings will be written.
*   `recordUseMapping`: Target `Uri` for recorded usage metadata maps (crucial for linking-time tree shaking).
*   `preamble`: Text inserted at the top of the generated file (licensing, annotations).
*   `format`: Set to `true` to run the Dart formatter automatically.

## Step-by-Step Workflow

### Step 1: Check/Add Dependencies
Open the package's `pubspec.yaml` and verify the `dev_dependencies` contains `ffigen`. Use the Dart MCP server or look up the latest version on [pub.dev](https://pub.dev/packages/ffigen) (e.g., `^20.1.1`).

You can add it automatically using the CLI:
```bash
dart pub add dev:ffigen
```

### Step 2: Formulate Paths Dynamically
Create a programmatic generator script under the package's `tool/` directory (e.g., `tool/ffigen.dart`).
Resolve paths relative to `Platform.script` to make sure it runs successfully from any working directory:

```dart
final packageRoot = Platform.script.resolve('../');
final headerFile = packageRoot.resolve('third_party/library.h');
final targetBindings = packageRoot.resolve('lib/src/third_party/bindings.g.dart');
```

### Step 3: Write the Script (`tool/ffigen.dart`)
Define `void main()` and run `FfiGenerator` with dynamic options (see complete example below).

### Step 4: Run Code Generation
Execute the script from the terminal inside the target package folder:
```bash
dart run tool/ffigen.dart
```

### Step 5: Static Analysis
Verify that the generated bindings are correct and resolve any analysis issues. FFIgen automatically runs the Dart formatter on the output file (via `format: true` configuration), so manual formatting is not required.

1.  Run the static analyzer inside the target package:
    ```bash
    dart analyze
    ```
2.  **Addressing Warnings/Lints**: If `dart analyze` reports style or lint warnings inside the generated file, append the corresponding warning codes to the `ignore_for_file:` list in your generator script's `preamble` configuration (e.g., adding `camel_case_types`, `non_constant_identifier_names`, etc.). Do not modify the package's global rules.
3.  **Addressing Compilation Errors**: If `dart analyze` reports actual compiler or analysis errors (not warnings) inside the generated file, do not attempt to edit the generated file manually. Report these error details directly to the user so they can file an issue on the repository at [github.com/dart-lang/native](https://github.com/dart-lang/native).


## Concrete Example: Binding a C Library

Let's assume we are working with the SQLite package under `pkgs/code_assets/example/sqlite`, which embeds SQLite C library sources inside `third_party/sqlite/` and accesses it via FFI.

### The C Header File (`third_party/sqlite/sqlite3.h`)
```c
// The author disclaims copyright to this source code.

#ifndef SQLITE3_H_
#define SQLITE3_H_

const char *sqlite3_libversion(void);

#endif // SQLITE3_H_
```

### BEFORE: Manual FFI Binding (The Anti-Pattern)
A developer might attempt to handcraft this integration. It is fragile, blocks tree-shaking metadata, and is highly prone to ABI and structural mapping issues:

```dart
// lib/src/sqlite3_manual.dart
import 'dart:ffi' as ffi;
import 'package:ffi/ffi.dart';

// Flaw 1: Hardcoded DynamicLibrary lookup blocks integration with modern native asset compilation.
final ffi.DynamicLibrary _dylib = ffi.DynamicLibrary.open('libsqlite3.so');

// Flaw 2: Manual function type matching requires writing redundant dynamic lookup boilerplate and lacks tree-shaking metadata.
typedef _sqlite3_libversion_C = ffi.Pointer<ffi.Char> Function();
typedef _sqlite3_libversion_Dart = ffi.Pointer<ffi.Char> Function();

final _sqlite3_libversion_Dart sqlite3LibVersion = _dylib
    .lookup<ffi.NativeFunction<_sqlite3_libversion_C>>('sqlite3_libversion')
    .asFunction();
```

### AFTER: Generating via FFIgen (The Correct Pattern)

Create a programmatic script at `tool/ffigen.dart`:

```dart
// Copyright (c) 2025, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:io';
import 'package:ffigen/ffigen.dart';

void main() {
  // Resolve paths dynamically relative to Platform.script
  final packageRoot = Platform.script.resolve('../');
  final entryHeader = packageRoot.resolve('third_party/sqlite/sqlite3.h');
  final bindingsOutput = packageRoot.resolve('lib/src/third_party/sqlite3.g.dart');
  final treeShakeMapping = packageRoot.resolve('lib/src/third_party/sqlite3.record_use_mapping.g.dart');

  FfiGenerator(
    headers: Headers(
      entryPoints: [entryHeader],
    ),
    functions: Functions(
      include: (decl) => {'sqlite3_libversion'}.contains(decl.originalName),
      // Essential for package optimization and tree-shaking
      recordUse: (_) => true,
    ),
    output: Output(
      dartFile: bindingsOutput,
      recordUseMapping: treeShakeMapping,
      format: true,
      preamble: '''

// AUTO-GENERATED FILE - DO NOT MODIFY.
// Generated via ffigen.
// To regenerate: dart run tool/ffigen.dart

// ignore_for_file: type=lint, unused_import, unused_element, deprecated_member_use_from_same_package, experimental_member_use
''',
    ),
  ).generate();

  print('Successfully generated sqlite3 FFI bindings.');
}
```

### Running the Generator script
Run this in the package root directory:
```bash
dart run tool/ffigen.dart
```

This will automatically create:
1.  `lib/src/third_party/sqlite3.g.dart`
2.  `lib/src/third_party/sqlite3.record_use_mapping.g.dart`

## Verification Checklist

Always perform the following verification before completing a binding generation task:

1.  **Correct Setup**: Verify the target generated files are inside `lib/src/third_party/` (required for third-party licensed code) and the primary FFI bindings file strictly uses the `.g.dart` extension.
2.  **Static Analysis**: Run `dart analyze` and ensure there are zero compiler/analyzer errors or warnings in the package.
    *   If static warnings are reported in the generated bindings, suppress them by adding `ignore_for_file` rules to the generator's `preamble` configuration (do not modify global package rules).
    *   If actual compiler or analyzer errors are reported in the generated bindings, do not edit the generated file manually. Report the details to the user and direct them to file an issue at [github.com/dart-lang/native](https://github.com/dart-lang/native).

© flutter · BSD-3-Clause · flutter/agent-plugins

Смотрите также

Спонсоры проекта

Компании, которые помогают держать аналитику открытой