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 风格写!" 用小学生词汇写说明书
相关推荐
QuantumLeap丶1 小时前
《Flutter全栈开发实战指南:从零到高级》- 05 - 基础组件实战:构建登录界面
flutter·ios
黄毛火烧雪下1 小时前
(四)Flutter插件之IOS插件开发
flutter·ios
西西学代码2 小时前
Flutter---弹窗
flutter
RaidenLiu2 小时前
告别陷阱:精通Flutter Signals的生命周期、高级API与调试之道
前端·flutter·前端框架
—Qeyser4 小时前
Flutter字体引用与使用指南
flutter
I烟雨云渊T5 小时前
iOS原生与Flutter的交互编程
flutter·ios·交互
恋猫de小郭8 小时前
第一台 Andriod XR 设备发布,Jetpack Compose XR 有什么不同?对原生开发有何影响?
android·前端·flutter
未来猫咪花9 小时前
对 signals.dart 细粒度更新的误解
flutter
—Qeyser1 天前
使用 Flutter 的 Positioned 控件实现精准布局
flutter
weixin_404611341 天前
鸿蒙flutter 老项目到新项目的遇到迁移坑点
flutter·华为·harmonyos