Flutter 如何使用 Dart FFI 和 Golang 進行調(diào)用
本項目提供了一個完整的基礎(chǔ)框架,演示如何使用 Flutter 的 Dart FFI(Foreign Function Interface)直接調(diào)用 Golang 代碼,并支持所有 Flutter 平臺(Android、iOS、Windows、macOS、Linux 和 Web)。通過此框架,開發(fā)者可以省去傳統(tǒng)的通過平臺代碼(如 Java/Kotlin、Swift/Objective-C)橋接的繁瑣步驟,直接實現(xiàn) Dart 與 Golang 的交互。
功能簡介
- 跨平臺支持:支持 Android、iOS、Windows、macOS、Linux 和 Web 平臺。
- 純 FFI 調(diào)用:無需通過平臺中間代碼轉(zhuǎn)換,Dart 可直接調(diào)用 Golang 方法。
- 示例 Demo:實現(xiàn)了一個從 Golang 定時回調(diào)當前時間到 Flutter 的功能。
- 簡單集成:開發(fā)者僅需 minimal 配置,即可在項目中直接使用。
- Web 兼容:支持 Web 平臺,但要求 Golang 代碼中不存在 IO 操作。
框架工作原理
-
Dart FFI:通過 Dart FFI,F(xiàn)lutter 項目直接調(diào)用本地 Golang 動態(tài)庫(如
.so、.dylib、.dll)。 - Web 平臺支持:通過 Golang 的 WebAssembly 輸出,使 Dart 能夠在 Web 平臺運行 Golang 代碼。
- 統(tǒng)一接口:框架提供統(tǒng)一的接口規(guī)范,開發(fā)者只需遵循規(guī)范聲明和實現(xiàn)接口,無需處理底層平臺差異。
使用指南
1. 下載和初始化項目
克隆本項目到您的本地開發(fā)環(huán)境:
git clone https://github.com/yaooort/go2flutter.git
cd go2flutter
2. 編譯 Golang 代碼
Golang 代碼庫位于 core 目錄下,您需要將希望暴露給 Flutter 調(diào)用的方法分別定義在以下文件中:
-
原生平臺:
core/export/cgo/main.go -
Web 平臺:
core/export/web/main.go
框架已提供一個示例代碼(定時器回調(diào)當前時間),可參考擴展。完成方法定義后,運行以下命令編譯所有平臺的 Golang 動態(tài)庫:
make all
編譯完成后,生成的庫文件位于 core/build 目錄:
- 原生動態(tài)庫(如
.so、.dll、.dylib)位于core/build/native。 - WebAssembly 文件(
.wasm)位于core/build/web。
3. 在 Flutter 中聲明 Golang 方法
- 打開 Flutter 項目的
lib/src/native_interface.dart文件。 - 按以下方式聲明并實現(xiàn) Golang 方法:
- 聲明與 Golang 對應(yīng)的函數(shù)接口。
- 為 Web 平臺實現(xiàn)特定的調(diào)用邏輯。
- 為其他平臺實現(xiàn)通用的 FFI 調(diào)用。
以下是一個示例接口聲明:
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();
}
具體實現(xiàn)請參考框架中已提供的 native_native_interface.dart 和 web_native_interface.dart 文件。
4. 在項目中引入插件
在您的 Flutter 項目的 pubspec.yaml 文件中添加以下依賴:
dependencies:
go:
path: ./go2flutter
確保將路徑指向本框架的實際路徑。
5. 使用示例
框架提供了一個 example 功能:Golang 定時器每秒回調(diào)當前時間到 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 應(yīng)用后,您將在控制臺中看到 Go 端定時返回的時間。
項目目錄結(jié)構(gòu)
go2flutter/
│
├── core/ # Golang 代碼庫
│ ├── export/ # Golang 方法定義目錄
│ │ ├── cgo/ # 原生平臺方法
│ │ └── web/ # Web 平臺方法
│ └── ... # 其他 Golang 源文件
│
├── lib/ # Flutter 代碼庫
│ ├── src/ # FFI 和接口實現(xiàn)
│ │ ├── native_interface.dart # 接口聲明
│ │ ├── native_universal.dart # 原生平臺實現(xiàn)
│ │ └── native_web.dart # Web 平臺實現(xiàn)
│ └── ...
注意事項
-
Web 平臺限制:
- Golang 代碼在 Web 平臺上運行時,不支持 IO 操作。
- 需要通過 WebAssembly 編譯生成
.wasm文件。
-
編譯工具鏈要求:
- 需要安裝
make工具。 - Golang 環(huán)境版本要求:1.17 及以上。
- 需要安裝
-
動態(tài)庫兼容性:
- 各平臺編譯的動態(tài)庫文件需與運行環(huán)境匹配。
- 生成的動態(tài)庫文件包含平臺差異,請確保正確加載。
開發(fā)者擴展
-
新增 Golang 方法:
- 在
core/export/cgo/main.go或core/export/web/main.go中定義方法。 - 確保方法簽名符合框架規(guī)范。
- 在
-
擴展 Dart 接口:
- 在
lib/src/native_interface.dart中添加方法聲明。 - 在
native_native_interface.dart和web_native_interface.dart中實現(xiàn)。
- 在
支持和貢獻
歡迎貢獻代碼或提交問題報告!如果您在使用中遇到問題,請通過 Issue 與我們聯(lián)系。
結(jié)語
通過本項目,開發(fā)者可以方便地在 Flutter 項目中調(diào)用 Golang 方法,無需處理平臺中間代碼轉(zhuǎn)換,簡化了開發(fā)流程。希望您能從中獲益! ??