1. FFI Plugin介绍

FFI (Foreign Function Interface) Plugin是Flutter框架提供的一种特殊插件类型,它允许Flutter代码直接调用本地C/C++/Rust等原生语言编写的函数,无需通过MethodChannel等间接通信方式。这种直接调用方式具有更高的性能,特别适合需要处理大量计算或与底层系统交互的场景。

1.1 核心特性

  • 高性能调用:直接调用本地原生代码,避免了通道通信的开销
  • 跨平台支持:支持Android、iOS和OpenHarmony等多平台
  • 简单易用的API:通过自动生成的Dart绑定代码使用本地函数
  • 灵活的配置:支持自定义编译选项和依赖管理

1.2 OpenHarmony适配特性

  • 完全支持OpenHarmony平台的Native开发
  • 与OpenHarmony的Native API无缝集成
  • 支持OpenHarmony的HAR包格式
  • 兼容Flutter官方的FFI开发流程

2. 环境准备

在开始开发和使用FFI Plugin之前,需要搭建完整的开发环境。

2.1 安装必要工具

  1. DevEco Studio:OpenHarmony官方开发IDE
  2. JDK 17:OpenHarmony SDK的Java环境依赖
  3. OpenHarmony版Flutter SDK:从AtomGit获取
  4. C/C++编译工具链
    • Linux:GCC/G++
    • Mac:Xcode Command Line Tools
    • Windows:Visual Studio Build Tools
  5. Dart FFI工具
    dart pub global activate ffigen
    

2.2 配置环境变量

# 国内镜像(可选)
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

# Flutter SDK路径
export PATH=/path/to/flutter_flutter/bin:$PATH

# OpenHarmony SDK
export TOOL_HOME=/Applications/DevEco-Studio.app/Contents # mac环境
export DEVECO_SDK_HOME=$TOOL_HOME/sdk
export PATH=$TOOL_HOME/tools/ohpm/bin:$PATH
export PATH=$TOOL_HOME/tools/hvigor/bin:$PATH
export PATH=$TOOL_HOME/tools/node/bin:$PATH

# C/C++编译工具链(根据系统配置)
# Linux/macOS
export PATH=/usr/local/bin:$PATH
# Windows
# SET PATH=C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64;%PATH%

3. 创建FFI Plugin

3.1 初始化FFI Plugin项目

使用Flutter CLI创建一个支持OpenHarmony的FFI Plugin:

# 创建支持Android、iOS和OpenHarmony的FFI Plugin
flutter create --template=plugin_ffi hello_ffi --platforms=android,ios,ohos

# 进入项目目录
cd hello_ffi

3.2 项目结构

创建的FFI Plugin项目包含以下主要目录和文件:

hello_ffi/
├── android/           # Android平台相关代码
├── ios/               # iOS平台相关代码
├── ohos/              # OpenHarmony平台相关代码
│   ├── entry/         # 应用入口模块
│   └── libs/          # 原生库目录
├── lib/               # Flutter Dart代码目录
│   ├── hello_ffi.dart # FFI Plugin的Dart接口
│   └── src/           # 原生函数的Dart绑定
├── native/            # 本地原生代码目录
│   ├── hello_ffi.c    # C语言实现的原生函数
│   └── hello_ffi.h    # C语言头文件
├── pubspec.yaml       # 项目依赖配置文件
└── ffigen.yaml        # ffigen工具配置文件

3.3 配置pubspec.yaml

pubspec.yaml文件中配置FFI Plugin支持的平台:

plugin:
  platforms:
    android:
      ffiPlugin: true
    ohos:
      ffiPlugin: true
    ios:
      ffiPlugin: true

# 添加ffigen依赖
dev_dependencies:
  ffigen: ^8.0.2
  package_config: ^2.1.0
  plugin_platform_interface: ^2.1.3

4. 开发FFI Plugin的原生代码

4.1 编写C语言头文件

native/hello_ffi.h文件中定义原生函数的接口:

#ifndef HELLO_FFI_H
#define HELLO_FFI_H

#include <stdint.h>

#ifdef _WIN32
#  ifdef HELLO_FFI_EXPORTS
#    define HELLO_FFI_EXPORT __declspec(dllexport)
#  else
#    define HELLO_FFI_EXPORT __declspec(dllimport)
#  endif
#else
#  define HELLO_FFI_EXPORT __attribute__((visibility("default")))
#endif

#ifdef __cplusplus
extern "C" {
#endif

// 简单的求和函数
HELLO_FFI_EXPORT int32_t hello_ffi_sum(int32_t a, int32_t b);

// 计算斐波那契数列(耗时操作)
HELLO_FFI_EXPORT int32_t hello_ffi_fibonacci(int32_t n);

#ifdef __cplusplus
}
#endif

#endif  // HELLO_FFI_H

4.2 实现C语言函数

native/hello_ffi.c文件中实现原生函数:

#include "hello_ffi.h"

// 简单的求和函数
int32_t hello_ffi_sum(int32_t a, int32_t b) {
  return a + b;
}

// 计算斐波那契数列(递归实现,故意设计为耗时操作)
int32_t hello_ffi_fibonacci(int32_t n) {
  if (n <= 1) {
    return n;
  }
  return hello_ffi_fibonacci(n - 1) + hello_ffi_fibonacci(n - 2);
}

5. 生成Dart绑定代码

使用ffigen工具自动生成Dart绑定代码,避免手动编写复杂的FFI绑定。

5.1 配置ffigen.yaml

在项目根目录下的ffigen.yaml文件中配置生成规则:

name: HelloFfiBindings
description: Auto-generated bindings for Hello FFI Plugin.
output: 'lib/src/hello_ffi_bindings_generated.dart'
headers:
  entry-points:
    - 'native/hello_ffi.h'
  include-directives:
    - 'native/hello_ffi.h'
preamble: |
  // ignore_for_file: always_specify_types
  // ignore_for_file: camel_case_types
  // ignore_for_file: non_constant_identifier_names

5.2 生成绑定代码

执行以下命令生成Dart绑定代码:

dart run ffigen --config ffigen.yaml

生成的绑定代码将位于lib/src/hello_ffi_bindings_generated.dart文件中。

6. 实现Dart接口

lib/hello_ffi.dart文件中实现FFI Plugin的Dart接口:

import 'dart:ffi';
import 'dart:isolate';

import 'src/hello_ffi_bindings_generated.dart';

// 加载原生库
final DynamicLibrary _dylib = () {
  if (dart.library.io.Platform.isAndroid || dart.library.io.Platform.isOHOS) {
    return DynamicLibrary.open('libhello_ffi.so');
  } else if (dart.library.io.Platform.isIOS) {
    return DynamicLibrary.process();
  } else {
    throw UnsupportedError('当前平台不支持');
  }
}();

// 创建绑定实例
final HelloFfiBindings _bindings = HelloFfiBindings(_dylib);

/// Hello FFI Plugin的Dart接口
class HelloFfi {
  /// 计算两个整数的和(直接调用,适合耗时短的操作)
  static int sum(int a, int b) {
    return _bindings.hello_ffi_sum(a, b);
  }

  /// 计算斐波那契数列(异步调用,适合耗时长的操作)
  static Future<int> fibonacci(int n) async {
    // 创建一个隔离线程执行耗时操作,避免阻塞UI
    return await Isolate.run(() => _bindings.hello_ffi_fibonacci(n));
  }
}

7. 在Flutter项目中使用FFI Plugin

7.1 引入FFI Plugin

在Flutter项目的pubspec.yaml文件中添加对我们开发的FFI Plugin的依赖:

dependencies:
  flutter:
    sdk: flutter

  # 以Git形式引入适配OpenHarmony的hello_ffi包
  hello_ffi:
    git:
      url: "https://atomgit.com/"
      path: "packages/hello_ffi/hello_ffi"

7.2 运行依赖获取命令

flutter pub get

7.3 调用FFI Plugin的API

在Flutter项目的Dart代码中使用FFI Plugin的API:

import 'package:flutter/material.dart';
import 'package:hello_ffi/hello_ffi.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FFI Plugin Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const HelloFfiScreen(),
    );
  }
}

class HelloFfiScreen extends StatefulWidget {
  const HelloFfiScreen({Key? key}) : super(key: key);

  
  State<HelloFfiScreen> createState() => _HelloFfiScreenState();
}

class _HelloFfiScreenState extends State<HelloFfiScreen> {
  int _sumResult = 0;
  int _fibonacciResult = 0;
  bool _isCalculating = false;

  // 计算两个数的和
  void _calculateSum() {
    const a = 10;
    const b = 20;
    final result = HelloFfi.sum(a, b);
    setState(() {
      _sumResult = result;
    });
  }

  // 异步计算斐波那契数列
  Future<void> _calculateFibonacci() async {
    const n = 30;
    setState(() {
      _isCalculating = true;
    });
    final result = await HelloFfi.fibonacci(n);
    setState(() {
      _fibonacciResult = result;
      _isCalculating = false;
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('FFI Plugin示例')),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text('FFI Plugin功能演示'),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _calculateSum,
              child: const Text('计算 10 + 20'),
            ),
            const SizedBox(height: 10),
            Text('计算结果: $_sumResult'),
            const SizedBox(height: 30),
            ElevatedButton(
              onPressed: _isCalculating ? null : _calculateFibonacci,
              child: _isCalculating
                  ? const CircularProgressIndicator(color: Colors.white)
                  : const Text('计算斐波那契数列 (n=30)'),
            ),
            const SizedBox(height: 10),
            Text('斐波那契数列结果: $_fibonacciResult'),
          ],
        ),
      ),
    );
  }
}

8. 构建与运行

8.1 构建FFI Plugin

在FFI Plugin项目目录下执行以下命令构建插件:

# 构建Android平台的库
flutter build apk --debug

# 构建OpenHarmony平台的库
flutter build hap --debug

8.2 运行Flutter应用

在使用FFI Plugin的Flutter项目目录下执行以下命令运行应用:

# 运行到OpenHarmony设备或模拟器
flutter run --debug -d device_id

9. 注意事项

  1. 原生代码性能

    • 耗时短的原生函数可以直接调用
    • 耗时长的原生函数应该在隔离线程中异步调用,避免阻塞UI线程
  2. 内存管理

    • 注意管理原生代码分配的内存,避免内存泄漏
    • 使用callocfree函数管理内存
  3. 平台兼容性

    • 不同平台的原生库加载方式不同
    • Android和OpenHarmony使用DynamicLibrary.open('libxxx.so')
    • iOS使用DynamicLibrary.process()
  4. 类型安全

    • 确保Dart类型与原生类型正确匹配
    • 使用ffi.Int32ffi.Double等类型定义

10. 总结

FFI Plugin是Flutter框架提供的一种高性能跨平台通信方案,它允许Flutter代码直接调用本地原生代码。在OpenHarmony平台上,FFI Plugin已完成适配,为开发者提供了强大的跨平台开发能力。

通过本文的介绍,您可以了解到:

  • FFI Plugin的概念和核心特性
  • 如何创建和开发适配OpenHarmony的FFI Plugin
  • 如何编写原生代码并生成Dart绑定
  • 如何在Flutter项目中引入和使用FFI Plugin
  • 最佳实践和注意事项

FFI Plugin的适配为开发者提供了一种新的跨平台开发选择,它结合了Flutter的UI开发效率和原生代码的高性能,使得开发者可以构建更加复杂和高性能的跨平台应用。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐