Flutter基础(FFI)

​1️⃣ 项目结构(先创建这些文件)​

复制代码
my_ffi_app/
├── lib/
│   ├── main.dart          # Flutter 主界面
│   └── native_add.c       # C 语言代码(FFI 调用的核心)
├── android/
│   └── app/
│       └── build.gradle   # Android 配置
└── ios/
    └── Runner.xcworkspace # iOS 自动配置(Xcode 管理)

​2️⃣ C 代码:lib/native_add.c

cpp 复制代码
#include <stdint.h> // 引入标准整数类型(如 int32_t)

// 告诉编译器:按C风格编译(Dart只能调C风格函数)
extern "C" {
    // 标记函数为"可见"(防止被编译器优化删除)
    __attribute__((visibility("default")))
    // 标记函数为"被使用"(确保链接时保留)
    __attribute__((used))
    // 定义一个加法函数(返回 int32_t,参数为 x, y)
    int32_t native_add(int32_t x, int32_t y) {
        return x + y; // 最简单的加法!
    }
}

​3️⃣ Android 配置:android/app/build.gradle

cpp 复制代码
android {
    defaultConfig {
        // ... 其他配置
        externalNativeBuild {
            cmake {
                path "../CMakeLists.txt" // 指定 CMake 配置文件路径
            }
        }
    }
}

👉 ​​新建 android/app/CMakeLists.txt​(文件名固定!):

cpp 复制代码
cmake_minimum_required(VERSION 3.6) # 要求 CMake 最低版本
add_library( # 编译一个动态库(Android 叫 .so)
    native_add         # 库名(随便起)
    SHARED             # 类型:动态库
    ../../lib/native_add.c  # C 文件路径(从项目根目录算)
)

4️⃣ iOS 配置(自动!)​

✅ 无需额外配置!Xcode 会自动识别 ios/Runner 下的 .c 文件。

​5️⃣ Dart 代码:lib/main.dart

Dart 复制代码
import 'package:flutter/material.dart';
import 'dart:ffi';    // FFI 核心库
import 'dart:io';     // 用于判断平台(Android/iOS)

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: FutureBuilder(
            future: _calculate(), // 异步执行 FFI 调用
            builder: (ctx, snapshot) => Text("1+2=${snapshot.data}"),
          ),
        ),
      ),
    );
  }

  Future<int> _calculate() async {
    // 第一步:加载动态库(Android 和 iOS 方式不同)
    final dylib = Platform.isAndroid
        ? DynamicLibrary.open("libnative_add.so")  // Android 库名
        : DynamicLibrary.process();                // iOS 直接读进程

    // 第二步:查找 C 函数符号(按名称找函数)
    final nativeAdd = dylib.lookupFunction<
        Int32 Function(Int32, Int32), // C 函数签名(输入输出类型)
        int Function(int, int)        // Dart 函数签名(自动转换类型)
    >("native_add");                  // 要查找的函数名

    // 第三步:像普通 Dart 函数一样调用!
    return nativeAdd(1, 2); // 输出 1+2=3
  }
}

6️⃣ 运行说明​

  1. ​Android​ :直接 flutter run
  2. ​iOS​ :先打开 ios/Runner.xcworkspace,用 Xcode 添加 native_add.c 文件(右键 Runner → Add Files)

​🧠 核心概念解释(小学生版)​

关键词 作用 类比
​FFI​ 让 Dart 和 C 语言互相通话的"翻译官" 会说两国语言的机器人
​DynamicLibrary​ 加载 C 编译好的动态库(.so.dylib 打开一本外文书
​lookupFunction​ 在书里查找指定的函数(按函数名) 翻到书的第 XX 页
​extern "C"​ 告诉 C++ 编译器:"别用复杂语法,用简单的 C 风格写!" 用小学生词汇写说明书
相关推荐
恋猫de小郭2 小时前
Flutter Riverpod 3.0 发布,大规模重构下的全新状态管理框架
android·前端·flutter
RaidenLiu4 小时前
Riverpod 3:重建控制的实践与性能优化指南
前端·flutter
蒋星熠20 小时前
Flutter跨平台工程实践与原理透视:从渲染引擎到高质产物
开发语言·python·算法·flutter·设计模式·性能优化·硬件工程
卢叁1 天前
Flutter之自定义TabIndicator
前端·flutter
萧雾宇1 天前
Android Compose打造仿现实逼真的烟花特效
android·flutter·kotlin
拜无忧1 天前
【教程】flutter常用知识点总结-针对小白
android·flutter·android studio
拜无忧1 天前
【教程】Flutter 高性能项目架构创建指南:从入门到高性能架构
android·flutter·android studio
醉过才知酒浓1 天前
flutter 拦截返回按钮的方法(WillPopScope or PopScope)
flutter
傅里叶1 天前
sudo启动Flutter程序AMD初始化失败
linux·flutter
苦逼的搬砖工1 天前
Flutter UI Components:闲来无事,设计整理了这几年来使用的UI组件库
前端·flutter