跳至主要內容

使用 dart:ffi 繫結至原生 iOS 程式碼

Flutter 行動和桌面應用程式可以使用 dart:ffi 函式庫來呼叫原生 C API。FFI 代表 外部函式介面。類似功能的其他術語包括原生介面語言繫結

在您的函式庫或程式使用 FFI 函式庫繫結至原生程式碼之前,您必須確保原生程式碼已載入,且其符號對 Dart 可見。本頁重點說明在 Flutter 外掛程式或應用程式中編譯、封裝和載入 iOS 原生程式碼。

本教學示範如何在 Flutter 外掛程式中組合 C/C++ 原始碼,並使用 Dart FFI 函式庫在 iOS 上繫結它們。在此演練中,您將建立一個實作 32 位元加法的 C 函式,然後透過名為「native_add」的 Dart 外掛程式公開它。

動態連結與靜態連結

#

原生函式庫可以動態或靜態連結至應用程式。靜態連結的函式庫會嵌入到應用程式的可執行映像檔中,並在應用程式啟動時載入。

可以使用 DynamicLibrary.executableDynamicLibrary.process 載入靜態連結函式庫中的符號。

相反地,動態連結函式庫會在應用程式內的個別檔案或資料夾中散佈,並依需求載入。在 iOS 上,動態連結函式庫以 .framework 資料夾散佈。

可以使用 DynamicLibrary.open 將動態連結函式庫載入 Dart 中。

API 文件可從Dart API 參考文件取得。

建立 FFI 外掛程式

#

若要建立名為「native_add」的 FFI 外掛程式,請執行下列動作

flutter create --platforms=android,ios,macos,windows,linux --template=plugin_ffi native_add
cd native_add

這會在外掛程式的 native_add/src 中建立 C/C++ 原始碼。這些原始碼是由各種作業系統建置資料夾中的原生建置檔案所建置。

FFI 函式庫只能繫結至 C 符號,因此在 C++ 中,這些符號會標記為 extern "C"

您也應該新增屬性,指出這些符號是從 Dart 參考的,以防止連結器在連結時最佳化期間捨棄這些符號。__attribute__((visibility("default"))) __attribute__((used))

在 iOS 上,native_add/ios/native_add.podspec 會連結程式碼。

原生程式碼會從 lib/native_add_bindings_generated.dart 中的 dart 叫用。

繫結是使用 package:ffigen 產生。

其他使用案例

#

iOS 和 macOS

#

動態連結器會在應用程式啟動時自動載入動態連結函式庫。可以使用 DynamicLibrary.process 解析其組成的符號。您也可以使用 DynamicLibrary.open 取得函式庫的控制代碼,以限制符號解析的範圍,但不清楚 Apple 的審查流程如何處理此問題。

可以使用 DynamicLibrary.executableDynamicLibrary.process 解析靜態連結到應用程式二進位檔中的符號。

平台函式庫

#

若要連結至平台函式庫,請使用下列指示

  1. 在 Xcode 中,開啟 Runner.xcworkspace
  2. 選取目標平台。
  3. 按一下 連結 Frameworks 和 Libraries 區段中的 +
  4. 選取要連結的系統函式庫。

第一方函式庫

#

第一方原生函式庫可以包含為原始碼或 (已簽署) .framework 檔案。也可能包含靜態連結的封存檔,但需要測試。

原始碼

#

若要直接連結至原始碼,請使用下列指示

  1. 在 Xcode 中,開啟 Runner.xcworkspace

  2. 將 C/C++/Objective-C/Swift 原始檔新增至 Xcode 專案。

  3. 將下列前置詞新增至匯出的符號宣告,以確保它們對 Dart 可見

    C/C++/Objective-C

    objc
    extern "C" /* <= C++ only */ __attribute__((visibility("default"))) __attribute__((used))

    Swift

    swift
    @_cdecl("myFunctionName")

已編譯 (動態) 函式庫

#

若要連結至已編譯的動態函式庫,請使用下列指示

  1. 如果存在正確簽署的 Framework 檔案,請開啟 Runner.xcworkspace
  2. 將 framework 檔案新增至 嵌入的二進位檔 區段。
  3. 也將它新增至 Xcode 中目標的 連結 Frameworks & Libraries 區段。

開放原始碼第三方函式庫

#

若要建立包含 C/C++/Objective-C Dart 程式碼的 Flutter 外掛程式,請使用下列指示

  1. 在您的外掛程式專案中,開啟 ios/<myproject>.podspec
  2. 將原生程式碼新增至 source_files 欄位。

接著,原生程式碼會靜態連結至任何使用此外掛程式的應用程式二進位檔中。

封閉原始碼第三方函式庫

#

若要建立包含 Dart 原始碼的 Flutter 外掛程式,但以二進位形式散佈 C/C++ 函式庫,請使用下列指示

  1. 在您的外掛程式專案中,開啟 ios/<myproject>.podspec
  2. 新增 vendored_frameworks 欄位。請參閱CocoaPods 範例

去除 iOS 符號

#

建立發行封存 (IPA) 時,符號會由 Xcode 移除。

  1. 在 Xcode 中,前往 Target Runner > Build Settings > Strip Style
  2. All Symbols 變更為 Non-Global Symbols

其他資源

#

若要深入瞭解 C 互通性,請查看這些影片