Flutter 调用 go

Flutter 如何使用 Dart FFI 和 Golang 进行调用

本项目提供了一个完整的基础框架,演示如何使用 Flutter 的 Dart FFI(Foreign Function Interface)直接调用 Golang 代码,并支持所有 Flutter 平台(Android、iOS、Windows、macOS、Linux 和 Web)。通过此框架,开发者可以省去传统的通过平台代码(如 Java/Kotlin、Swift/Objective-C)桥接的繁琐步骤,直接实现 Dart 与 Golang 的交互。


功能简介

  • 跨平台支持:支持 Android、iOS、Windows、macOS、Linux 和 Web 平台。
  • 纯 FFI 调用:无需通过平台中间代码转换,Dart 可直接调用 Golang 方法。
  • 示例 Demo:实现了一个从 Golang 定时回调当前时间到 Flutter 的功能。
  • 简单集成:开发者仅需 minimal 配置,即可在项目中直接使用。
  • Web 兼容:支持 Web 平台,但要求 Golang 代码中不存在 IO 操作。

框架工作原理

  1. Dart FFI:通过 Dart FFI,Flutter 项目直接调用本地 Golang 动态库(如 .so.dylib.dll)。
  2. Web 平台支持:通过 Golang 的 WebAssembly 输出,使 Dart 能够在 Web 平台运行 Golang 代码。
  3. 统一接口:框架提供统一的接口规范,开发者只需遵循规范声明和实现接口,无需处理底层平台差异。

使用指南

1. 下载和初始化项目

克隆本项目到您的本地开发环境:

git clone https://github.com/yaooort/go2flutter.git
cd go2flutter

2. 编译 Golang 代码

Golang 代码库位于 core 目录下,您需要将希望暴露给 Flutter 调用的方法分别定义在以下文件中:

  • 原生平台core/export/cgo/main.go
  • Web 平台core/export/web/main.go

框架已提供一个示例代码(定时器回调当前时间),可参考扩展。完成方法定义后,运行以下命令编译所有平台的 Golang 动态库:

make all

编译完成后,生成的库文件位于 core/build 目录:

  • 原生动态库(如 .so.dll.dylib)位于 core/build/native
  • WebAssembly 文件(.wasm)位于 core/build/web

3. 在 Flutter 中声明 Golang 方法

  1. 打开 Flutter 项目的 lib/src/native_interface.dart 文件。
  2. 按以下方式声明并实现 Golang 方法:
    • 声明与 Golang 对应的函数接口。
    • 为 Web 平台实现特定的调用逻辑。
    • 为其他平台实现通用的 FFI 调用。

以下是一个示例接口声明:

class Message {
  late final String errMsg;
  late final String message;
  late final int code;

  Message(this.errMsg, this.message, this.code);
}

typedef OnMessage = void Function(Message message);

// 定义一个抽象类作为标准桥梁
abstract class NativeLibraryInterface {
  // test get go time
  String getTime();

  // 初始化
  Future<bool> init(OnMessage onMessage, {String token});

  // 停止
  stopWork();
}

具体实现请参考框架中已提供的 native_native_interface.dartweb_native_interface.dart 文件。


4. 在项目中引入插件

在您的 Flutter 项目的 pubspec.yaml 文件中添加以下依赖:

dependencies:
  go:
    path: ./go2flutter

确保将路径指向本框架的实际路径。


5. 使用示例

框架提供了一个 example 功能:Golang 定时器每秒回调当前时间到 Flutter。以下是示例用法:

  // 初始化平台版本
    NativeLibrary().init((message) {
      setState(() {
        _platformVersion = message.message;
      });
    }).then((bool isOk) {
      setState(() {
        _isOk = isOk;
      });
      if (kDebugMode) {
        print("初始化go:$isOk");
      }
    });


SnackBar(
                    content: Text('获取的时间: ${NativeLibrary().getTime()}'),
                    duration: const Duration(seconds: 2),
                  ),

运行 Flutter 应用后,您将在控制台中看到 Go 端定时返回的时间。


项目目录结构

go2flutter/
│
├── core/                  # Golang 代码库
│   ├── export/            # Golang 方法定义目录
│   │   ├── cgo/           # 原生平台方法
│   │   └── web/           # Web 平台方法
│   └── ...                # 其他 Golang 源文件
│
├── lib/                   # Flutter 代码库
│   ├── src/               # FFI 和接口实现
│   │   ├── native_interface.dart  # 接口声明
│   │   ├── native_universal.dart  # 原生平台实现
│   │   └── native_web.dart     # Web 平台实现
│   └── ...

注意事项

  1. Web 平台限制
    • Golang 代码在 Web 平台上运行时,不支持 IO 操作。
    • 需要通过 WebAssembly 编译生成 .wasm 文件。
  2. 编译工具链要求
    • 需要安装 make 工具。
    • Golang 环境版本要求:1.17 及以上。
  3. 动态库兼容性
    • 各平台编译的动态库文件需与运行环境匹配。
    • 生成的动态库文件包含平台差异,请确保正确加载。

开发者扩展

  1. 新增 Golang 方法
    • core/export/cgo/main.gocore/export/web/main.go 中定义方法。
    • 确保方法签名符合框架规范。
  2. 扩展 Dart 接口
    • lib/src/native_interface.dart 中添加方法声明。
    • native_native_interface.dartweb_native_interface.dart 中实现。

支持和贡献

欢迎贡献代码或提交问题报告!如果您在使用中遇到问题,请通过 Issue 与我们联系。


结语

通过本项目,开发者可以方便地在 Flutter 项目中调用 Golang 方法,无需处理平台中间代码转换,简化了开发流程。希望您能从中获益! 🎉

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容