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 风格写!" 用小学生词汇写说明书
相关推荐
大龄秃头程序员1 小时前
Flutter 最少代码验证:为什么子 Isolate 调原生,一定要先回到主 Isolate?
flutter
FungLeo2 小时前
成为全栈·Flutter App 篇·分类、标签与搜索:移动端内容发现
flutter·移动开发·标签·搜索·分类管理·成为全栈
m0_738185823 小时前
Flutter 鸿蒙化实战:the_apple_sign_in 适配 OpenHarmony,Apple 登录
flutter·华为·harmonyos·鸿蒙
m0_738185824 小时前
Flutter 鸿蒙化实战:umeng_analytics_plugin 适配 OpenHarmony,友盟统计
flutter·华为·harmonyos·鸿蒙
FungLeo5 小时前
成为全栈·Flutter App 篇·列表分页与下拉刷新:去重、失败保留和返回位置
flutter·移动开发·下拉刷新·分页加载·列表优化·成为全栈
大龄秃头程序员7 小时前
【从一道面试题入手】深入理解 Dart 事件循环调度机制
flutter
恋猫de小郭7 小时前
Kotlin 2.5 的 Companion 改造,对 KMP 的重要升级
android·前端·flutter
程序员老刘1 天前
Flutter你看看人家RN
flutter·react native·ai编程
大龄秃头程序员1 天前
【Flutter Bloc 从 0 到 1】用最少代码跑通 Bloc
flutter
m0_738185821 天前
Flutter 鸿蒙化实战:sqflite 适配 OpenHarmony,本地 SQLite 数据库
flutter·华为·harmonyos·鸿蒙