Flutter ffi開發(fā)通過(guò) ffigen 生成函數(shù)簽名綁定

前言:

最近在入坑 flutter ffi(筆者目前對(duì)flutter dart也不是很了解),先從最難的啃,網(wǎng)上現(xiàn)在關(guān)于 ffi的文章很少,對(duì)于新手而言不太友好,更別說(shuō)公開的視頻教程,更是少之又少,我也是摸索了很久才入一點(diǎn)門道(太菜了,哥哥們諒解),這里不做任何技術(shù)上的指導(dǎo),只是簡(jiǎn)簡(jiǎn)單單的入門。

分幾個(gè)步驟來(lái):

第一步:搭建flutter環(huán)境
第二步:創(chuàng)建flutter 新項(xiàng)目
第三步:引入 ffigen
第四步:引入 .h/.c 文件
第五步:使用 ffigen 生成dart上可執(zhí)行的簽名文件(dart語(yǔ)言不能直接調(diào)用c語(yǔ)言中的函數(shù),類似 Android中的 jni,需要做下中轉(zhuǎn))
第六步:編譯 C 代碼為動(dòng)態(tài)庫(kù)
第七步:加載動(dòng)態(tài)庫(kù)并調(diào)用內(nèi)部 C 函數(shù)
第八步:運(yùn)行
總結(jié)


廢話不多說(shuō),直接開干

一:搭建flutter ffigen所需環(huán)境

詳細(xì)看這里:https://codelabs.developers.google.com/codelabs/flutter-ffigen?hl=zh-cn#0
(主要看:安裝 LLVM,其它的看這篇文檔)

二:創(chuàng)建flutter 新項(xiàng)目

通過(guò)命令行創(chuàng)建 或 Android Studio,Visual Studio Code 編譯器創(chuàng)建都行

flutter create first_flutter_ffi_study_project
cd first_flutter_ffi_study_project
如果是通過(guò)模板生成的頂層 pubpsec.yaml 可能包含過(guò)時(shí)的 ffigen 軟件包版本。運(yùn)行以下命令,更新插件項(xiàng)目中的 Dart 依賴項(xiàng):
$ flutter pub upgrade --major-versions

三:引入 ffigen

flutter pub add ffi
flutter pub add ffigen --dev
// pubspec.yaml
......
dependencies:
  ffi: ^2.1.3

.....

dev_dependencies:
  ffigen: ^15.0.0
......

四:引入 .h/.c 文件

在項(xiàng)目根目錄創(chuàng)建 native 文件夾并新建 hello.h 和 hello.c 文件

mkdir native
cd native
touch hello.h
touch hello.c
// hello.h
#ifndef HELLO_H
#define HELLO_H

int sum(int a, int b);

#endif // HELLO_H
// hello.c
#include "hello.h"

int sum(int a, int b) {
    return a + b;
}

五:使用 ffigen 生成 dart 和 C 綁定的簽名文件

首先,你需要編寫一個(gè) ffigen 配置文件。在項(xiàng)目的根目錄下創(chuàng)建一個(gè) ffigen.yaml 文件,內(nèi)容如下:

name: FFIBinding
description: FFI bindings for the native library.
output: lib/src/ffi_bindings.dart

headers:
  entry-points:
    - 'native/hello.h'
  include-directives:
    - 'native/hello.h'

然后,在終端中運(yùn)行 ffigen 命令生成 Dart 綁定:

flutter pub run ffigen --config ffigen.yaml

這會(huì)在 lib/src 目錄下生成一個(gè) ffi_bindings.dart 文件。

六:編譯 C 代碼為動(dòng)態(tài)庫(kù)

為了能夠在 Dart 中調(diào)用 c語(yǔ)言中的函數(shù),你需要先編譯 C 代碼為動(dòng)態(tài)庫(kù)。

在 macOS 上,導(dǎo)航到 native 文件夾,運(yùn)行以下命令:(這將在 native 目錄下生成 libhello.dylib 文件)

gcc -dynamiclib -o libhello.dylib hello.c

在 Windows 上,你可以使用 MinGW 或者 Visual Studio 的命令行工具來(lái)編譯。
使用 MinGW
安裝 MinGW,確保 gcc 在你的系統(tǒng)路徑中。
打開終端,導(dǎo)航到 native 文件夾,運(yùn)行以下命令:(這將在當(dāng)前目錄下生成 hello.dll 文件)

gcc -shared -o hello.dll hello.c

?。?!Android 和 ios 這里后面再補(bǔ)充(待更新)

七:加載動(dòng)態(tài)庫(kù)并調(diào)用內(nèi)部 C 函數(shù)

在 lib/main.dart 文件中導(dǎo)入生成的綁定文件,并調(diào)用 sum 函數(shù):

import 'package:flutter/material.dart';
import 'dart:ffi'; // 導(dǎo)入 FFI 包
import 'src/ffi_bindings.dart' as bindings; // 導(dǎo)入生成的綁定文件

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('FFI Example')),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              // 加載動(dòng)態(tài)庫(kù)
              final DynamicLibrary nativeLib = DynamicLibrary.open('hello.dll'); // windows 使用 'hello.dll' 對(duì)于 macos,使用 'libhello.dylib'

              // 獲取生成的綁定文件中的函數(shù)
              final sumFunction = bindings.FFIBinding(nativeLib).sum;

              // 調(diào)用函數(shù)
              final result = sumFunction(10, 20);
              print('Sum of 10 and 20 is $result');
            },
            child: Text('Call sum function'),
          ),
        ),
      ),
    );
  }
}

八:運(yùn)行

flutter run

點(diǎn)擊按鈕后,你應(yīng)該能在控制臺(tái)看到輸出:(至此已完成初步入門,然后再回顧下這幾個(gè)要點(diǎn))

Sum of 10 and 20 is 30

示例源碼:點(diǎn)這里

總結(jié):

通過(guò)上面的步驟,大致知道了,ffi 到底怎么開發(fā),以及 ffigen 到底怎么使用,從量變到質(zhì)變,加油少年!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容