Flutter自动生成代码插件ffigen_app_test_137的使用

Flutter自动生成代码插件ffigen_app_test_137的使用

ffigen_app_test_137

ffigen_app_test_137 是一个新的 Flutter FFI 插件项目。


入门指南

这个项目是一个用于 Flutter 的 FFI 插件的起点,它是一种专门的包,直接通过 Dart FFI 调用本地代码。


项目结构

此模板使用以下结构:

  • src: 包含本地源代码以及用于构建动态库的 CmakeFile.txt 文件。
  • lib: 包含定义插件 API 的 Dart 代码,并使用 dart:ffi 调用本地代码。
  • 平台文件夹 (android, ios, windows 等): 包含用于将本地代码库与平台应用程序一起构建和捆绑的构建文件。
.
├── android
│   └── build.gradle
├── ios
│   └── ffigen_app_test_137.podspec
├── lib
│   ├── ffigen_app_test_137.dart
│   └── ...
├── linux
│   └── CMakeLists.txt
├── src
│   ├── ffigen_app_test_137.h
│   └── native_code.c
├── windows
│   └── CMakeLists.txt
└── pubspec.yaml

构建和捆绑本地代码

pubspec.yaml 中指定 FFI 插件如下:

plugin:
  platforms:
    some_platform:
      ffiPlugin: true

这种配置会为各个目标平台调用本地构建,并将二进制文件捆绑到使用这些 FFI 插件的 Flutter 应用程序中。

可以结合 dartPluginClass 使用,例如当 FFI 用于联邦插件的一个平台实现时:

plugin:
  implements: some_other_plugin
  platforms:
    some_platform:
      dartPluginClass: SomeClass
      ffiPlugin: true

插件可以同时拥有 FFI 和方法通道:

plugin:
  platforms:
    some_platform:
      pluginClass: SomeName
      ffiPlugin: true

由 FFI(和方法通道)插件调用的本地构建系统包括:

  • Android: Gradle,它调用 Android NDK 进行本地构建。
    • 参见 android/build.gradle 文档。
  • iOS 和 MacOS: Xcode,通过 CocoaPods。
    • 参见 ios/ffigen_app_test_137.podspec 文档。
    • 参见 macos/ffigen_app_test_137.podspec 文档。
  • Linux 和 Windows: CMake。
    • 参见 linux/CMakeLists.txt 文档。
    • 参见 windows/CMakeLists.txt 文档。

绑定到本地代码

要使用本地代码,Dart 需要绑定。为了避免手动编写这些绑定,它们可以通过 package:ffigen 从头文件生成(src/ffigen_app_test_137.h)。

重新生成绑定的方法是运行以下命令:

flutter pub run ffigen --config ffigen.yaml

调用本地代码

非常短的本地函数可以直接从任何隔离区调用。例如,参见 lib/ffigen_app_test_137.dart 中的 sum

长时间运行的函数应在辅助隔离区中调用,以避免在 Flutter 应用程序中丢失帧。例如,参见 lib/ffigen_app_test_137.dart 中的 sumAsync

// lib/ffigen_app_test_137.dart

import 'dart:ffi' as ffi;
import 'dart:io';

void main() {
  // 直接调用短时间运行的函数
  int result = sum(5, 10);
  print('Sum: $result');

  // 异步调用长时间运行的函数
  sumAsync(5, 10).then((value) => print('Async Sum: $value'));
}

// 定义本地函数签名
final _sum = _nativeLibrary.lookupFunction<
    Int32 Function(Int32, Int32),
    int Function(int, int)>('sum');

int sum(int a, int b) {
  return _sum(a, b);
}

// 异步调用示例
Future<int> sumAsync(int a, int b) async {
  final completer = Completer<int>();
  compute(sum, [a, b]).then((value) => completer.complete(value));
  return completer.future;
}

Flutter 帮助

如需了解有关 Flutter 的更多信息,请查看我们的在线文档,其中包含教程、示例、移动开发指南以及完整的 API 参考。


示例代码完整演示

以下是完整的代码示例,展示如何使用 ffigen_app_test_137 插件:

src/ffigen_app_test_137.h

// src/ffigen_app_test_137.h

#ifndef FFIGEN_APP_TEST_137_H
#define FFIGEN_APP_TEST_137_H

int sum(int a, int b);

#endif // FFIGEN_APP_TEST_137_H

src/native_code.c

// src/native_code.c

#include "ffigen_app_test_137.h"

int sum(int a, int b) {
  return a + b;
}

pubspec.yaml

name: ffigen_app_test_137
version: 1.0.0
environment:
  sdk: ">=2.18.0 <3.0.0"
dependencies:
  flutter:
    sdk: flutter
  ffi: ^2.0.0
dev_dependencies:
  ffigen: ^5.0.0
  build_runner: ^2.0.0

lib/ffigen_app_test_137.dart

// lib/ffigen_app_test_137.dart

import 'dart:ffi' as ffi;
import 'dart:io';
import 'package:flutter/services.dart' show rootBundle;

void main() {
  // 直接调用短时间运行的函数
  int result = sum(5, 10);
  print('Sum: $result');

  // 异步调用长时间运行的函数
  sumAsync(5, 10).then((value) => print('Async Sum: $value'));
}

// 加载本地库
final DynamicLibrary _nativeLibrary = Platform.isWindows
    ? DynamicLibrary.process()
    : Platform.isMacOS
        ? DynamicLibrary.open('libffigen_app_test_137.dylib')
        : DynamicLibrary.open('libffigen_app_test_137.so');

// 定义本地函数签名
final _sum = _nativeLibrary.lookupFunction<
    Int32 Function(Int32, Int32),
    int Function(int, int)>('sum');

int sum(int a, int b) {
  return _sum(a, b);
}

// 异步调用示例
Future<int> sumAsync(int a, int b) async {
  final completer = Completer<int>();
  compute(sum, [a, b]).then((value) => completer.complete(value));
  return completer.future;
}

更多关于Flutter自动生成代码插件ffigen_app_test_137的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自动生成代码插件ffigen_app_test_137的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


ffigen 是一个用于 Flutter 和 Dart 的代码生成工具,它可以帮助你自动生成 Dart 代码来与 C/C++ 代码进行交互。ffigen 通过解析 C/C++ 头文件并生成相应的 Dart 绑定代码,使得在 Dart 中调用 C/C++ 函数变得更加容易。

使用 ffigen 的步骤

  1. 添加依赖: 在你的 pubspec.yaml 文件中添加 ffigen 依赖:

    dev_dependencies:
      ffigen: ^7.0.0
    
  2. 配置 ffigen: 在项目根目录下创建一个 ffigen.yaml 文件,用于配置 ffigen 的行为。以下是一个简单的配置示例:

    name: 'NativeLibrary'
    description: 'Bindings to native C/C++ library'
    output: 'lib/native_bindings.dart'
    headers:
      entry-points:
        - 'path/to/your/header.h'
      include-directories:
        - 'path/to/include'
    
    • name: 生成的 Dart 库的名称。
    • description: 生成的库的描述。
    • output: 生成的 Dart 文件的输出路径。
    • headers: 配置要解析的头文件路径和包含目录。
  3. 运行 ffigen: 在终端中运行以下命令来生成 Dart 绑定代码:

    flutter pub run ffigen
    

    这将会根据 ffigen.yaml 配置文件生成 Dart 代码,并输出到指定的文件中。

  4. 使用生成的代码: 生成的 Dart 代码可以直接在你的 Flutter 项目中使用。例如,如果你生成了一个名为 NativeLibrary 的库,你可以这样使用它:

    import 'native_bindings.dart';
    
    void main() {
      var result = NativeLibrary.someFunction();
      print(result);
    }
    

示例项目

假设你有一个名为 lib.h 的 C 头文件,内容如下:

#ifndef LIB_H
#define LIB_H

int add(int a, int b);

#endif

你可以按照以下步骤生成 Dart 绑定代码:

  1. 创建 ffigen.yaml

    name: 'NativeLibrary'
    description: 'Bindings to native C library'
    output: 'lib/native_bindings.dart'
    headers:
      entry-points:
        - 'lib.h'
      include-directories:
        - '.'
    
  2. 运行 ffigen

    flutter pub run ffigen
    
  3. 使用生成的代码

    import 'native_bindings.dart';
    
    void main() {
      var result = NativeLibrary.add(3, 4);
      print(result); // 输出 7
    }
回到顶部