From 4801143d93e2c444ed8eafeffde9b03f160e8cd7 Mon Sep 17 00:00:00 2001 From: CFUG Dev Team <47591151+cfug-dev@users.noreply.github.com> Date: Mon, 22 Jun 2026 13:21:16 -0400 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=AA=84=20[translator=20bot]=20Update?= =?UTF-8?q?=20sites/docs/src/content/platform-integration/legacy-ffi-plugi?= =?UTF-8?q?n.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../platform-integration/legacy-ffi-plugin.md | 389 +++++++++++++++++- 1 file changed, 387 insertions(+), 2 deletions(-) diff --git a/sites/docs/src/content/platform-integration/legacy-ffi-plugin.md b/sites/docs/src/content/platform-integration/legacy-ffi-plugin.md index 534e6a0336..0b97d3292c 100644 --- a/sites/docs/src/content/platform-integration/legacy-ffi-plugin.md +++ b/sites/docs/src/content/platform-integration/legacy-ffi-plugin.md @@ -1,22 +1,42 @@ --- -title: Bind to native code using the legacy FFI plugin template -description: >- +# title: Bind to native code using the legacy FFI plugin template +title: 使用旧版 FFI plugin 模板绑定到原生代码 +# description: >- +description: Use the legacy plugin_ffi template and dart:ffi to bind to native C code in your Flutter plugin or app. +ai-translated: true --- :::warning + This page documents the legacy `plugin_ffi` approach to C interop. +本页面介绍了旧版 `plugin_ffi` 的 C 语言互操作方法。 + Since Flutter 3.38, we recommend using the `package_ffi` template with [build hooks][] for C interop. +自 Flutter 3.38 起,我们建议使用 `package_ffi` 模板和 +[构建 hook][build hooks] 进行 C 语言互操作。 + However, the legacy FFI plugin template (`plugin_ffi`) documented here is still useful if you need to: +然而,如果需要以下操作,此处记录的旧版 FFI plugin 模板(`plugin_ffi`)仍然有用: + - Access the Flutter Plugin API. + + 访问 Flutter Plugin API。 + - Use static linking (on iOS and macOS). + + 使用静态链接(在 iOS 和 macOS 上)。 + - Configure a Google Play services runtime on Android. + + 在 Android 上配置 Google Play services 运行时。 + ::: Flutter mobile and desktop apps can @@ -25,6 +45,11 @@ _FFI_ stands for [_foreign function interface._][FFI] Other terms for similar functionality include _native interface_ and _language bindings._ +Flutter 移动和桌面应用可以使用 [`dart:ffi`][`dart:ffi`] 库调用原生 C API。 +**FFI** 代表 [**foreign function interface.**][FFI] +类似功能的其他术语包括 +**原生接口** 和 **语言绑定。** + [build hooks]: /platform-integration/bind-native-code [`dart:ffi`]: {{site.dart.api}}/dart-ffi/dart-ffi-library.html [FFI]: https://en.wikipedia.org/wiki/Foreign_function_interface @@ -36,87 +61,167 @@ loaded and its symbols are visible to Dart. This page focuses on compiling, packaging, and loading native code within a Flutter plugin or app. +在你的库或程序可以使用 FFI 库绑定到原生代码之前, +你必须确保原生代码已加载并且其符号对 Dart 可见。 +本页面重点介绍在 Flutter plugin 或应用中编译、打包、 +和加载原生代码。 + This tutorial demonstrates how to bundle C/C++ sources in a Flutter plugin and bind to them using the Dart FFI library. In this walkthrough, you'll create a C function that implements 32-bit addition and then exposes it through a Dart plugin named `native_add`. +本教程演示了如何在 Flutter plugin 中捆绑 C/C++ 源码 +并使用 Dart FFI 库绑定它们。 +在本演练中,你将创建一个实现 32 位加法的 C 函数, +然后通过名为 `native_add` 的 Dart plugin 公开它。 + ## Dynamic versus static linking +## 动态链接与静态链接 + A native library can be linked into an app either dynamically or statically. A statically linked library is embedded into the app's executable image, and is loaded when the app starts. +原生库可以动态或静态地链接到应用中。 +静态链接库嵌入到应用的执行映像中, +并在应用启动时加载。 + Symbols from a statically linked library can be loaded using [`DynamicLibrary.executable`][] or [`DynamicLibrary.process`][]. +可以使用 [`DynamicLibrary.executable`][`DynamicLibrary.executable`] 或 +[`DynamicLibrary.process`][`DynamicLibrary.process`] 加载静态链接库中的符号。 + A dynamically linked library, by contrast, is distributed in a separate file or folder within the app, and loaded on-demand. The distribution format depends on the platform: +相比之下,动态链接库以单独的文件或文件夹形式分发在应用内, +并按需加载。分发格式取决于 +平台: + - On Android, a dynamically linked library is distributed as a set of `.so` (ELF) files, one for each architecture. Only dynamic libraries are supported, because the main executable is the JVM, which Flutter doesn't link to statically. + + 在 Android 上,动态链接库以一组 `.so` (ELF) 文件形式分发,每个架构一个。 + 只支持动态库, + 因为主可执行文件是 JVM, + 而 Flutter 不会静态链接到它。 + - On iOS and macOS, the dynamically linked library is distributed as a `.framework` folder. + 在 iOS 和 macOS 上,动态链接库以 `.framework` 文件夹形式分发。 + A dynamically linked library can be loaded into Dart using [`DynamicLibrary.open`][]. +可以使用 [`DynamicLibrary.open`][`DynamicLibrary.open`] 将动态链接库加载到 +Dart 中。 + [`DynamicLibrary.executable`]: {{site.dart.api}}/dart-ffi/DynamicLibrary/DynamicLibrary.executable.html [`DynamicLibrary.open`]: {{site.dart.api}}/dart-ffi/DynamicLibrary/DynamicLibrary.open.html [`DynamicLibrary.process`]: {{site.dart.api}}/dart-ffi/DynamicLibrary/DynamicLibrary.process.html ## Create an FFI plugin +## 创建 FFI plugin + To create an FFI plugin called `native_add`, use `flutter create` with the `plugin_ffi` template: +要创建名为 `native_add` 的 FFI plugin, +请使用 `flutter create` 和 `plugin_ffi` 模板: + ```console $ flutter create --platforms=android,ios,macos,windows,linux --template=plugin_ffi native_add ``` :::note + You can exclude platforms from `--platforms` that you don't want to build to. However, you need to include the platform of the device you are testing on. + +你可以从 `--platforms` 中排除你不想构建到的平台。 +但是,你需要包含你正在测试的设备的平台。 + ::: This creates a plugin with C/C++ sources in `native_add/src`. These sources are built by the native build files in the various OS build folders. +这会在 `native_add/src` 中创建一个包含 C/C++ 源码的 plugin。 +这些源码由各个操作系统构建文件夹中的原生构建文件构建。 + The FFI library can only bind against C symbols, so in C++ these symbols are marked `extern "C"`. +FFI 库只能绑定 C 符号, +因此在 C++ 中,这些符号被标记为 `extern "C"`。 + You should also add attributes to indicate that the symbols are referenced from Dart, to prevent the linker from discarding the symbols during link-time optimization: `__attribute__((visibility("default"))) __attribute__((used))`. +你还应该添加属性来指示这些 +符号是从 Dart 引用的, +以防止链接器在链接时优化期间丢弃这些符号: +`__attribute__((visibility("default"))) __attribute__((used))`。 + The platform-specific build file links the code: +平台特定的构建文件链接代码: + - On Android, `native_add/android/build.gradle`. + + 在 Android 上,`native_add/android/build.gradle`。 + - On iOS, `native_add/ios/native_add.podspec`. + + 在 iOS 上,`native_add/ios/native_add.podspec`。 + - On macOS, `native_add/macos/native_add.podspec`. + + 在 macOS 上,`native_add/macos/native_add.podspec`。 + - On Linux, `native_add/linux/CMakeLists.txt`. + + 在 Linux 上,`native_add/linux/CMakeLists.txt`。 + - On Windows, `native_add/windows/CMakeLists.txt`. + 在 Windows 上,`native_add/windows/CMakeLists.txt`。 + The native code is invoked from Dart in `lib/native_add_bindings_generated.dart`. +原生代码从 +Dart 中的 `lib/native_add_bindings_generated.dart` 调用。 + The bindings are generated with [`package:ffigen`][]. +绑定是使用 [`package:ffigen`][`package:ffigen`] 生成的。 + [`package:ffigen`]: {{site.pub-pkg}}/ffigen ## Other use cases +## 其他用例 + +### iOS + ### iOS The dynamic linker automatically loads @@ -126,101 +231,199 @@ You can also get a handle to the library with [`DynamicLibrary.open`][] to restrict the scope of symbol resolution, but it's unclear how Apple's review process handles this. +动态链接器在应用启动时自动加载 +动态链接库。 +它们的组成符号可以使用 [`DynamicLibrary.process`][`DynamicLibrary.process`] 解析。 +你还可以使用 [`DynamicLibrary.open`][`DynamicLibrary.open`] 获取库的句柄以 +限制符号解析的范围,但 Apple 的审核流程如何处理这一点尚不清楚。 + Symbols statically linked into the application binary can be resolved using [`DynamicLibrary.executable`][] or [`DynamicLibrary.process`][]. +静态链接到应用二进制文件中的符号可以使用 +[`DynamicLibrary.executable`][`DynamicLibrary.executable`] 或 [`DynamicLibrary.process`][`DynamicLibrary.process`] 解析。 + #### Platform library {:#ios-platform-library} +#### 平台库 {:#ios-platform-library} + To link against a platform library, use the following instructions: +要链接到平台库, +请使用以下说明: + 1. In Xcode, open `Runner.xcworkspace`. + + 在 Xcode 中,打开 `Runner.xcworkspace`。 + 1. Select the target platform. + + 选择目标平台。 + 1. Click **+** in the **Linked Frameworks and Libraries** section. + + 在 **Linked Frameworks and Libraries** 部分中点击 **+**。 + 1. Select the system library to link against. + 选择要链接的系统库。 + #### First-party library {:#ios-first-party-library} +#### 第一方库 {:#ios-first-party-library} + A first-party native library can be included either as source or as a (signed) `.framework` file. It's probably possible to include statically linked archives as well, but it requires testing. +第一方原生库可以作为源码或作为(签名)`.framework` 文件包含。 +可能也可以包含静态链接的 +归档文件,但这需要测试。 + #### Source code {:#ios-source-code} +#### 源码 {:#ios-source-code} + To link directly to source code, use the following instructions: +要直接链接到源码, +请使用以下说明: + 1. In Xcode, open `Runner.xcworkspace`. + + 在 Xcode 中,打开 `Runner.xcworkspace`。 + 1. Add the C/C++/Objective-C/Swift source files to the Xcode project. + + 将 C/C++/Objective-C/Swift + 源码文件添加到 Xcode 项目中。 + 1. Add the following prefix to the exported symbol declarations to ensure they are visible to Dart: + 将以下前缀添加到导出的符号声明中,以 + 确保它们对 Dart 可见: + **C/C++/Objective-C:** + **C/C++/Objective-C:** + ```objc extern "C" /* <= C++ only */ __attribute__((visibility("default"))) __attribute__((used)) ``` **Swift:** + **Swift:** + ```swift @_cdecl("myFunctionName") ``` #### Compiled (dynamic) library {:#ios-compiled-dynamic-library} +#### 已编译(动态)库 {:#ios-compiled-dynamic-library} + To link to a compiled dynamic library, use the following instructions: +要链接到已编译的动态库, +请使用以下说明: + 1. If a properly signed `Framework` file is present, open `Runner.xcworkspace`. + + 如果存在正确签名的 `Framework` 文件,请打开 `Runner.xcworkspace`。 + 1. Add the framework file to the **Frameworks, Libraries, and Embedded Content** section of the target in Xcode. + + 将 framework 文件添加到 Xcode 中目标下的 **Frameworks, Libraries, and Embedded Content** 部分。 + 1. Under the **Embed** column, select **Embed & Sign**. + 在 **Embed** 列下,选择 **Embed & Sign**。 + #### Open-source third-party library {:#ios-open-source-third-party-library} +#### 开源第三方库 {:#ios-open-source-third-party-library} + To create a Flutter plugin that includes both C/C++/Objective-C _and_ Dart code, use the following instructions: +要创建一个同时包含 C/C++/Objective-C **and** Dart 代码的 Flutter plugin,请使用以下说明: + 1. In your plugin project, open `ios/.podspec`. + + 在你的 plugin 项目中,打开 `ios/.podspec`。 + 1. Add the native code to the `source_files` field. + 将原生代码添加到 `source_files` 字段。 + The native code is then statically linked into the application binary of any app that uses this plugin. +然后,原生代码会静态链接到使用此 plugin 的任何应用的应用程序二进制文件中。 + #### Closed-source third-party library {:#ios-closed-source-third-party-library} +#### 闭源第三方库 {:#ios-closed-source-third-party-library} + To create a Flutter plugin that includes Dart source code, but distribute the C/C++ library in binary form, use the following instructions: +要创建一个包含 Dart 源代码,但以二进制形式分发 C/C++ 库的 Flutter plugin,请使用以下说明: + 1. In your plugin project, open `ios/.podspec`. + + 在你的 plugin 项目中,打开 `ios/.podspec`。 + 1. Add a `vendored_frameworks` field. See the [CocoaPods example][]. + 添加一个 `vendored_frameworks` 字段。请参阅 [CocoaPods 示例][CocoaPods example]。 + :::warning + **Do not** upload this plugin (or any plugin containing binary code) to pub.dev. Instead, this plugin should be downloaded from a trusted third-party, as shown in the CocoaPods example. + +**不要** 将此 plugin (或任何包含二进制代码的 plugin) 上传到 pub.dev。相反,此 plugin 应从受信任的第三方下载,如 CocoaPods 示例所示。 + ::: [CocoaPods example]: {{site.github}}/CocoaPods/CocoaPods/blob/master/examples/Vendored%20Framework%20Example/Example%20Pods/VendoredFrameworkExample.podspec #### Stripping symbols {:#ios-stripping-symbols} +#### 剥离符号 {:#ios-stripping-symbols} + When creating a release build, Xcode strips the symbols. +创建发布版本时,Xcode 会剥离符号。 + 1. In Xcode, select the **Runner** target, then go to **Build Settings > Strip Style**. + + 在 Xcode 中,选择 **Runner** 目标,然后转到 **Build Settings > Strip Style**。 + 1. Change from **All Symbols** to **Non-Global Symbols**. + 从 **All Symbols** 更改为 **Non-Global Symbols**。 + +### macOS + ### macOS The dynamic linker automatically loads @@ -230,116 +433,246 @@ You can also get a handle to the library with [`DynamicLibrary.open`][] to restrict the scope of symbol resolution, but it's unclear how Apple's review process handles this. +动态链接器会在应用启动时自动加载动态链接库。它们的组成符号可以使用 [`DynamicLibrary.process`][`DynamicLibrary.process`] 解析。你也可以使用 [`DynamicLibrary.open`][`DynamicLibrary.open`] 获取库的句柄来限制符号解析的范围,但目前尚不清楚 Apple 的审核流程如何处理这种情况。 + Symbols statically linked into the application binary can be resolved using [`DynamicLibrary.executable`][] or [`DynamicLibrary.process`][]. +静态链接到应用程序二进制文件中的符号可以使用 [`DynamicLibrary.executable`][`DynamicLibrary.executable`] 或 [`DynamicLibrary.process`][`DynamicLibrary.process`] 解析。 + #### Platform library {:#macos-platform-library} +#### 平台库 {:#macos-platform-library} + To link against a platform library, use the following instructions: +要链接到平台库,请使用以下说明: + 1. In Xcode, open `Runner.xcworkspace`. + + 在 Xcode 中,打开 `Runner.xcworkspace`。 + 1. Select the target platform. + + 选择目标平台。 + 1. Click **+** in the **Linked Frameworks and Libraries** section. + + 在 **Linked Frameworks and Libraries** 部分中点击 **+**。 + 1. Select the system library to link against. + 选择要链接的系统库。 + #### First-party library {:#macos-first-party-library} +#### 第一方库 {:#macos-first-party-library} + A first-party native library can be included either as source or as a (signed) `.framework` file. It's probably possible to include statically linked archives as well, but it requires testing. +第一方原生库可以作为源代码或 (已签名的) `.framework` 文件包含在内。可能也可以包含静态链接的归档文件,但这需要测试。 + #### Source code {:#macos-source-code} +#### 源代码 {:#macos-source-code} + To link directly to source code, use the following instructions: +要直接链接到源代码,请使用以下说明: + 1. In Xcode, open `Runner.xcworkspace`. + + 在 Xcode 中,打开 `Runner.xcworkspace`。 + 1. Add the C/C++/Objective-C/Swift source files to the Xcode project. + + 将 C/C++/Objective-C/Swift 源文件添加到 Xcode 项目中。 + 1. Add the following prefix to the exported symbol declarations to ensure they are visible to Dart: + 将以下前缀添加到导出的符号声明中,以确保它们对 Dart 可见: + **C/C++/Objective-C:** + **C/C++/Objective-C:** + ```objc extern "C" /* <= C++ only */ __attribute__((visibility("default"))) __attribute__((used)) ``` **Swift:** + **Swift:** + ```swift @_cdecl("myFunctionName") ``` #### Compiled (dynamic) library {:#macos-compiled-dynamic-library} +#### 编译后的 (动态) 库 {:#macos-compiled-dynamic-library} + To link to a compiled dynamic library, use the following instructions: +要链接到编译后的动态库,请使用以下说明: + 1. If a properly signed `Framework` file is present, open `Runner.xcworkspace`. + + 如果存在正确签名的 `Framework` 文件,请打开 `Runner.xcworkspace`。 + 1. Add the framework file to the **Frameworks, Libraries, and Embedded Content** section of the target in Xcode. + + 将 framework 文件添加到 Xcode 中目标下的 **Frameworks, Libraries, and Embedded Content** 部分。 + 1. Under the **Embed** column, select **Embed & Sign**. + 在 **Embed** 列下,选择 **Embed & Sign**。 + #### Compiled (dynamic) library, closed source {:#macos-compiled-dynamic-library-closed-source} +#### 编译后的 (动态) 库,闭源 {:#macos-compiled-dynamic-library-closed-source} + To add a closed source library to a [Flutter macOS Desktop][] app, use the following instructions: +要将闭源库添加到 [Flutter macOS 桌面][Flutter macOS Desktop] 应用中,请使用以下说明: + 1. Follow the instructions for Flutter desktop to create a Flutter desktop app. + + 按照 Flutter 桌面版的说明创建一个 Flutter 桌面应用。 + 1. Open the `yourapp/macos/Runner.xcworkspace` in Xcode. + + 在 Xcode 中打开 `yourapp/macos/Runner.xcworkspace`。 + 1. Drag your precompiled library (`libyourlibrary.dylib`) into `Runner/Frameworks`. + + 将你的预编译库 (`libyourlibrary.dylib`) 拖到 `Runner/Frameworks` 中。 + 1. Click `Runner` and go to the `Build Phases` tab. + + 点击 `Runner` 并转到 `Build Phases` 选项卡。 + 1. Drag `libyourlibrary.dylib` into the `Copy Bundle Resources` list. + + 将 `libyourlibrary.dylib` 拖到 `Copy Bundle Resources` 列表中。 + 1. Under `Embed Libraries`, check `Code Sign on Copy`. + + 在 `Embed Libraries` 下,勾选 `Code Sign on Copy`。 + 1. Under `Link Binary With Libraries`, set status to `Optional`. (We use dynamic linking, no need to statically link.) + + 在 `Link Binary With Libraries` 下,将状态设置为 `Optional`。(我们使用动态链接,无需静态链接。) + 1. Click `Runner` and go to the `General` tab. + + 点击 `Runner` 并转到 `General` 选项卡。 + 1. Drag `libyourlibrary.dylib` into the **Frameworks, Libraries, and Embedded Content** list. + + 将 `libyourlibrary.dylib` 拖到 **Frameworks, Libraries, and Embedded Content** 列表中。 + 1. Select **Embed & Sign**. + + 选择 **Embed & Sign**。 + 1. Click **Runner** and go to the **Build Settings** tab. + + 点击 **Runner** 并转到 **Build Settings** 选项卡。 + 1. In the **Search Paths** section configure the **Library Search Paths** to include the path where `libyourlibrary.dylib` is located. + + 在 **Search Paths** 部分中,配置 **Library Search Paths** 以包含 `libyourlibrary.dylib` 所在的路径。 + 1. Edit `lib/main.dart`. + + 编辑 `lib/main.dart`。 + 1. Use `DynamicLibrary.open('libyourlibrary.dylib')` to dynamically link to the symbols. + + 使用 `DynamicLibrary.open('libyourlibrary.dylib')` 动态链接到符号。 + 1. Call your native function somewhere in a widget. + + 在 widget 中的某个地方调用你的原生函数。 + 1. Run `flutter run` and check that your native function gets called. + + 运行 `flutter run` 并检查你的原生函数是否被调用。 + 1. Run `flutter build macos` to build a self-contained release version of your app. + 运行 `flutter build macos` 来构建一个 + 独立的发布版本的应用。 + [Flutter macOS Desktop]: /platform-integration/macos/building #### Stripping symbols {:#macos-stripping-symbols} +#### 剥离符号 {:#macos-stripping-symbols} + When creating a release build, Xcode strips the symbols. +当创建发布版本时,Xcode 会剥离符号。 + 1. In Xcode, select the **Runner** target, then go to **Build Settings > Strip Style**. + + 在 Xcode 中,选择 **Runner** 目标, + 然后前往 **Build Settings > Strip Style**。 + 1. Change from **All Symbols** to **Non-Global Symbols**. + 从 **All Symbols** 更改为 **Non-Global Symbols**。 + +### Android + ### Android #### Platform library {:#android-platform-library} +#### 平台库 {:#android-platform-library} + To link against a platform library, use the following instructions: +要链接到平台库, +请使用以下说明: + 1. Find the desired library in the [Android NDK Native APIs][] list in the Android docs. This lists stable native APIs. + + 在 Android 文档的 [Android NDK Native APIs][Android NDK Native APIs] + 列表中找到所需的库。此列表包含稳定的原生 API。 + 1. Load the library using [`DynamicLibrary.open`][]. For example, to load OpenGL ES (v3): + 使用 [`DynamicLibrary.open`][`DynamicLibrary.open`] 加载库。 + 例如,加载 OpenGL ES (v3): + ```dart DynamicLibrary.open('libGLES_v3.so'); ``` @@ -347,35 +680,64 @@ use the following instructions: You might need to update the Android manifest file of the app or plugin if indicated by the documentation. +如果文档中有所指示,你可能需要更新应用或 plugin 的 +Android manifest 文件。 + [Android NDK Native APIs]: {{site.android-dev}}/ndk/guides/stable_apis #### First-party library {:#android-first-party-library} +#### 第一方库 {:#android-first-party-library} + The process for including native code in source code or binary form is the same for an app or plugin. +以源代码或二进制形式包含原生代码的 +过程对于应用或 plugin 来说是相同的。 + #### Open-source third-party library {:#android-open-source-third-party-library} +#### 开源第三方库 {:#android-open-source-third-party-library} + Follow the [Add C and C++ code to your project][] instructions in the Android docs to add native code and support for the native code toolchain (either CMake or `ndk-build`). +遵循 Android 文档中 [将 C 和 C++ 代码添加到你的项目][Add C and C++ code to your project] +的说明,以添加原生代码并支持原生 +代码工具链(无论是 CMake 还是 `ndk-build`)。 + [Add C and C++ code to your project]: {{site.android-dev}}/studio/projects/add-native-code #### Closed-source third-party library {:#android-closed-source-third-party-library} +#### 闭源第三方库 {:#android-closed-source-third-party-library} + To create a Flutter plugin that includes Dart source code, but distribute the C/C++ library in binary form, use the following instructions: +要创建一个包含 Dart 源代码, +但以二进制形式分发 C/C++ 库的 Flutter plugin, +请使用以下说明: + 1. Open the `android/build.gradle` file for your project. + + 打开你项目的 `android/build.gradle` 文件。 + 1. Add the AAR artifact as a dependency. **Don't** include the artifact in your Flutter package. Instead, it should be downloaded from a repository, such as Maven Central. + 将 AAR artifact 添加为依赖项。 + **不要** 将 artifact 包含在你的 Flutter package 中。 + 相反,它应该从仓库(例如 Maven Central)下载。 + #### Android APK size (shared object compression) +#### Android APK 大小(共享对象压缩) + [Android guidelines][] in general recommend distributing native shared objects uncompressed because that actually saves on device space. @@ -384,20 +746,43 @@ unpacking them on the device into a temporary location and then loading. APKs are additionally packed in transit—that's why you should be looking at download size. +[Android 指南][Android guidelines] 通常建议 +分发未压缩的原生共享对象, +因为这实际上节省了设备空间。 +共享对象可以直接从 APK 加载,而不是 +在设备上解压到临时位置再加载。 +APK 在传输过程中还会额外打包—这就是 +为什么你应该关注下载大小。 + By default, Flutter APKs compress `libflutter.so` and `libapp.so`, which leads to a smaller APK size but a larger on-device size. To control whether native libraries are stored compressed and extracted at install time, set the Android Gradle plugin's `useLegacyPackaging` option. For current recommendations, see the [Android guidelines][]. +默认情况下,Flutter APK 会压缩 `libflutter.so` 和 `libapp.so`, +这会导致 APK 大小更小,但设备上的大小更大。 +要控制原生库是否在安装时压缩和提取, +请设置 Android Gradle plugin 的 `useLegacyPackaging` 选项。 +有关当前建议,请参阅 [Android 指南][Android guidelines]。 + [Android guidelines]: {{site.android-dev}}/topic/performance/reduce-apk-size#extract-false ## Other resources +## 其他资源 + To learn more about C interoperability, check out these videos: +要了解更多关于 C 互操作性的信息,请查看这些视频: + - [C interoperability with Dart FFI][] + + [Dart FFI 的 C 互操作性][C interoperability with Dart FFI] + - [How to Use Dart FFI to Build a Retro Audio Player][] + [如何使用 Dart FFI 构建复古音频播放器][How to Use Dart FFI to Build a Retro Audio Player] + [C interoperability with Dart FFI]: {{site.yt.watch}}?v=2MMK7YoFgaA [How to Use Dart FFI to Build a Retro Audio Player]: {{site.yt.watch}}?v=05Wn2oM_nWw From 539fef8e46ca906fd270064423eb23c5aa6ee7db Mon Sep 17 00:00:00 2001 From: Amos Date: Tue, 23 Jun 2026 02:06:30 +0800 Subject: [PATCH 2/3] docs: platform-integration/legacy-ffi-plugin.md --- .../platform-integration/legacy-ffi-plugin.md | 94 +++++++++---------- 1 file changed, 44 insertions(+), 50 deletions(-) diff --git a/sites/docs/src/content/platform-integration/legacy-ffi-plugin.md b/sites/docs/src/content/platform-integration/legacy-ffi-plugin.md index 0b97d3292c..e0556c1408 100644 --- a/sites/docs/src/content/platform-integration/legacy-ffi-plugin.md +++ b/sites/docs/src/content/platform-integration/legacy-ffi-plugin.md @@ -2,9 +2,11 @@ # title: Bind to native code using the legacy FFI plugin template title: 使用旧版 FFI plugin 模板绑定到原生代码 # description: >- -description: - Use the legacy plugin_ffi template and dart:ffi to bind to - native C code in your Flutter plugin or app. +# Use the legacy plugin_ffi template and dart:ffi to bind to +# native C code in your Flutter plugin or app. +description: >- + 在 Flutter plugin 或应用中,使用旧版的 plugin_ffi 模板和 dart:ffi + 与原生 C 代码进行绑定。 ai-translated: true --- @@ -23,7 +25,7 @@ Since Flutter 3.38, we recommend using the `package_ffi` template with However, the legacy FFI plugin template (`plugin_ffi`) documented here is still useful if you need to: -然而,如果需要以下操作,此处记录的旧版 FFI plugin 模板(`plugin_ffi`)仍然有用: +然而,如果需要以下操作,此处记录的旧版 FFI plugin 模板 (`plugin_ffi`) 仍然有用: - Access the Flutter Plugin API. @@ -45,10 +47,10 @@ _FFI_ stands for [_foreign function interface._][FFI] Other terms for similar functionality include _native interface_ and _language bindings._ -Flutter 移动和桌面应用可以使用 [`dart:ffi`][`dart:ffi`] 库调用原生 C API。 -**FFI** 代表 [**foreign function interface.**][FFI] +Flutter 移动和桌面应用可以使用 [`dart:ffi`][] 库调用原生 C API。 +**FFI** 代表 [**foreign function interface(外部函数接口)**][FFI]。 类似功能的其他术语包括 -**原生接口** 和 **语言绑定。** +**原生接口 (native interface)** 和 **语言绑定 (language bindings)**。 [build hooks]: /platform-integration/bind-native-code [`dart:ffi`]: {{site.dart.api}}/dart-ffi/dart-ffi-library.html @@ -62,7 +64,7 @@ This page focuses on compiling, packaging, and loading native code within a Flutter plugin or app. 在你的库或程序可以使用 FFI 库绑定到原生代码之前, -你必须确保原生代码已加载并且其符号对 Dart 可见。 +你必须确保原生代码已加载并且其 Symbols 符号对 Dart 可见。 本页面重点介绍在 Flutter plugin 或应用中编译、打包、 和加载原生代码。 @@ -94,8 +96,8 @@ Symbols from a statically linked library can be loaded using [`DynamicLibrary.executable`][] or [`DynamicLibrary.process`][]. -可以使用 [`DynamicLibrary.executable`][`DynamicLibrary.executable`] 或 -[`DynamicLibrary.process`][`DynamicLibrary.process`] 加载静态链接库中的符号。 +可以使用 [`DynamicLibrary.executable`][] 或 +[`DynamicLibrary.process`][] 加载静态链接库中的 Symbols 符号。 A dynamically linked library, by contrast, is distributed in a separate file or folder within the app, @@ -125,7 +127,7 @@ the platform: A dynamically linked library can be loaded into Dart using [`DynamicLibrary.open`][]. -可以使用 [`DynamicLibrary.open`][`DynamicLibrary.open`] 将动态链接库加载到 +可以使用 [`DynamicLibrary.open`][] 将动态链接库加载到 Dart 中。 [`DynamicLibrary.executable`]: {{site.dart.api}}/dart-ffi/DynamicLibrary/DynamicLibrary.executable.html @@ -166,8 +168,8 @@ various OS build folders. The FFI library can only bind against C symbols, so in C++ these symbols are marked `extern "C"`. -FFI 库只能绑定 C 符号, -因此在 C++ 中,这些符号被标记为 `extern "C"`。 +FFI 库只能绑定 C Symbols 符号, +因此在 C++ 中,这些 Symbols 符号被标记为 `extern "C"`。 You should also add attributes to indicate that the symbols are referenced from Dart, @@ -176,8 +178,8 @@ during link-time optimization: `__attribute__((visibility("default"))) __attribute__((used))`. 你还应该添加属性来指示这些 -符号是从 Dart 引用的, -以防止链接器在链接时优化期间丢弃这些符号: +Symbols 符号是从 Dart 引用的, +以防止链接器在链接时优化期间丢弃这些 Symbols 符号: `__attribute__((visibility("default"))) __attribute__((used))`。 The platform-specific build file links the code: @@ -212,7 +214,7 @@ Dart 中的 `lib/native_add_bindings_generated.dart` 调用。 The bindings are generated with [`package:ffigen`][]. -绑定是使用 [`package:ffigen`][`package:ffigen`] 生成的。 +绑定是使用 [`package:ffigen`][] 生成的。 [`package:ffigen`]: {{site.pub-pkg}}/ffigen @@ -222,8 +224,6 @@ The bindings are generated with [`package:ffigen`][]. ### iOS -### iOS - The dynamic linker automatically loads dynamically linked libraries when the app starts. Their constituent symbols can be resolved using [`DynamicLibrary.process`][]. @@ -233,15 +233,15 @@ unclear how Apple's review process handles this. 动态链接器在应用启动时自动加载 动态链接库。 -它们的组成符号可以使用 [`DynamicLibrary.process`][`DynamicLibrary.process`] 解析。 -你还可以使用 [`DynamicLibrary.open`][`DynamicLibrary.open`] 获取库的句柄以 -限制符号解析的范围,但 Apple 的审核流程如何处理这一点尚不清楚。 +它们的组成 Symbols 符号可以使用 [`DynamicLibrary.process`][] 解析。 +你还可以使用 [`DynamicLibrary.open`][] 获取库的 handle 以 +限制 Symbols 符号解析的范围,但 Apple 的审核流程如何处理这一点尚不清楚。 Symbols statically linked into the application binary can be resolved using [`DynamicLibrary.executable`][] or [`DynamicLibrary.process`][]. -静态链接到应用二进制文件中的符号可以使用 -[`DynamicLibrary.executable`][`DynamicLibrary.executable`] 或 [`DynamicLibrary.process`][`DynamicLibrary.process`] 解析。 +静态链接到应用二进制文件中的 Symbols 符号可以使用 +[`DynamicLibrary.executable`][] 或 [`DynamicLibrary.process`][] 解析。 #### Platform library {:#ios-platform-library} @@ -305,21 +305,17 @@ use the following instructions: 1. Add the following prefix to the exported symbol declarations to ensure they are visible to Dart: - 将以下前缀添加到导出的符号声明中,以 + 将以下前缀添加到导出的 Symbol 符号声明中,以 确保它们对 Dart 可见: **C/C++/Objective-C:** - **C/C++/Objective-C:** - ```objc extern "C" /* <= C++ only */ __attribute__((visibility("default"))) __attribute__((used)) ``` **Swift:** - **Swift:** - ```swift @_cdecl("myFunctionName") ``` @@ -357,7 +353,7 @@ To create a Flutter plugin that includes both C/C++/Objective-C _and_ Dart code, use the following instructions: -要创建一个同时包含 C/C++/Objective-C **and** Dart 代码的 Flutter plugin,请使用以下说明: +要创建一个同时包含 C/C++/Objective-C **和** Dart 代码的 Flutter plugin,请使用以下说明: 1. In your plugin project, open `ios/.podspec`. @@ -370,7 +366,7 @@ use the following instructions: The native code is then statically linked into the application binary of any app that uses this plugin. -然后,原生代码会静态链接到使用此 plugin 的任何应用的应用程序二进制文件中。 +然后,原生代码会静态链接到任何使用此 plugin 的应用程序二进制文件中。 #### Closed-source third-party library {:#ios-closed-source-third-party-library} @@ -399,7 +395,8 @@ Instead, this plugin should be downloaded from a trusted third-party, as shown in the CocoaPods example. -**不要** 将此 plugin (或任何包含二进制代码的 plugin) 上传到 pub.dev。相反,此 plugin 应从受信任的第三方下载,如 CocoaPods 示例所示。 +**不要** 将此 plugin(或任何包含二进制代码的 plugin)上传到 pub.dev。 +相反,此 plugin 应从受信任的第三方下载,如 CocoaPods 示例所示。 ::: @@ -407,11 +404,11 @@ as shown in the CocoaPods example. #### Stripping symbols {:#ios-stripping-symbols} -#### 剥离符号 {:#ios-stripping-symbols} +#### 剥离 Symbols 符号 {:#ios-stripping-symbols} When creating a release build, Xcode strips the symbols. -创建发布版本时,Xcode 会剥离符号。 +创建发布版本时,Xcode 会剥离 Symbols 符号。 1. In Xcode, select the **Runner** target, then go to **Build Settings > Strip Style**. @@ -424,8 +421,6 @@ When creating a release build, Xcode strips the symbols. ### macOS -### macOS - The dynamic linker automatically loads dynamically linked libraries when the app starts. Their constituent symbols can be resolved using [`DynamicLibrary.process`][]. @@ -433,12 +428,16 @@ You can also get a handle to the library with [`DynamicLibrary.open`][] to restrict the scope of symbol resolution, but it's unclear how Apple's review process handles this. -动态链接器会在应用启动时自动加载动态链接库。它们的组成符号可以使用 [`DynamicLibrary.process`][`DynamicLibrary.process`] 解析。你也可以使用 [`DynamicLibrary.open`][`DynamicLibrary.open`] 获取库的句柄来限制符号解析的范围,但目前尚不清楚 Apple 的审核流程如何处理这种情况。 +动态链接器会在应用启动时自动加载动态链接库。 +它们的组成 Symbols 符号可以使用 [`DynamicLibrary.process`][] 解析。 +你也可以使用 [`DynamicLibrary.open`][] 获取库的句柄来限制 Symbols 符号解析的范围, +但目前尚不清楚 Apple 的审核流程如何处理这种情况。 Symbols statically linked into the application binary can be resolved using [`DynamicLibrary.executable`][] or [`DynamicLibrary.process`][]. -静态链接到应用程序二进制文件中的符号可以使用 [`DynamicLibrary.executable`][`DynamicLibrary.executable`] 或 [`DynamicLibrary.process`][`DynamicLibrary.process`] 解析。 +静态链接到应用程序二进制文件中的 Symbols 符号可以使用 [`DynamicLibrary.executable`][] 或 +[`DynamicLibrary.process`][] 解析。 #### Platform library {:#macos-platform-library} @@ -474,7 +473,8 @@ as source or as a (signed) `.framework` file. It's probably possible to include statically linked archives as well, but it requires testing. -第一方原生库可以作为源代码或 (已签名的) `.framework` 文件包含在内。可能也可以包含静态链接的归档文件,但这需要测试。 +第一方原生库可以作为源代码或 (已签名的) `.framework` 文件包含在内。 +可能也可以包含静态链接的归档文件,但这需要测试。 #### Source code {:#macos-source-code} @@ -497,20 +497,16 @@ use the following instructions: 1. Add the following prefix to the exported symbol declarations to ensure they are visible to Dart: - 将以下前缀添加到导出的符号声明中,以确保它们对 Dart 可见: + 将以下前缀添加到导出的 Symbols 符号声明中,以确保它们对 Dart 可见: **C/C++/Objective-C:** - **C/C++/Objective-C:** - ```objc extern "C" /* <= C++ only */ __attribute__((visibility("default"))) __attribute__((used)) ``` **Swift:** - **Swift:** - ```swift @_cdecl("myFunctionName") ``` @@ -611,7 +607,7 @@ use the following instructions: 1. Use `DynamicLibrary.open('libyourlibrary.dylib')` to dynamically link to the symbols. - 使用 `DynamicLibrary.open('libyourlibrary.dylib')` 动态链接到符号。 + 使用 `DynamicLibrary.open('libyourlibrary.dylib')` 动态链接到 Symbols 符号。 1. Call your native function somewhere in a widget. @@ -631,11 +627,11 @@ use the following instructions: #### Stripping symbols {:#macos-stripping-symbols} -#### 剥离符号 {:#macos-stripping-symbols} +#### 剥离 Symbols 符号 {:#macos-stripping-symbols} When creating a release build, Xcode strips the symbols. -当创建发布版本时,Xcode 会剥离符号。 +当创建发布版本时,Xcode 会剥离 Symbols 符号。 1. In Xcode, select the **Runner** target, then go to **Build Settings > Strip Style**. @@ -649,8 +645,6 @@ When creating a release build, Xcode strips the symbols. ### Android -### Android - #### Platform library {:#android-platform-library} #### 平台库 {:#android-platform-library} @@ -664,7 +658,7 @@ use the following instructions: 1. Find the desired library in the [Android NDK Native APIs][] list in the Android docs. This lists stable native APIs. - 在 Android 文档的 [Android NDK Native APIs][Android NDK Native APIs] + 在 Android 文档的 [Android NDK Native APIs][] 列表中找到所需的库。此列表包含稳定的原生 API。 1. Load the library using [`DynamicLibrary.open`][]. @@ -761,7 +755,7 @@ install time, set the Android Gradle plugin's `useLegacyPackaging` option. For current recommendations, see the [Android guidelines][]. 默认情况下,Flutter APK 会压缩 `libflutter.so` 和 `libapp.so`, -这会导致 APK 大小更小,但设备上的大小更大。 +这会导致 APK 文件更小,但设备上的文件更大。 要控制原生库是否在安装时压缩和提取, 请设置 Android Gradle plugin 的 `useLegacyPackaging` 选项。 有关当前建议,请参阅 [Android 指南][Android guidelines]。 From 6aa557875e6bfbb4d88b9d9a96771b4e06617b61 Mon Sep 17 00:00:00 2001 From: Amos Date: Tue, 23 Jun 2026 02:14:20 +0800 Subject: [PATCH 3/3] docs: platform-integration/legacy-ffi-plugin.md --- .../platform-integration/legacy-ffi-plugin.md | 114 +++++++++--------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/sites/docs/src/content/platform-integration/legacy-ffi-plugin.md b/sites/docs/src/content/platform-integration/legacy-ffi-plugin.md index e0556c1408..a60e76208f 100644 --- a/sites/docs/src/content/platform-integration/legacy-ffi-plugin.md +++ b/sites/docs/src/content/platform-integration/legacy-ffi-plugin.md @@ -255,19 +255,19 @@ use the following instructions: 1. In Xcode, open `Runner.xcworkspace`. - 在 Xcode 中,打开 `Runner.xcworkspace`。 + 在 Xcode 中,打开 `Runner.xcworkspace`。 1. Select the target platform. - 选择目标平台。 + 选择目标平台。 1. Click **+** in the **Linked Frameworks and Libraries** section. - 在 **Linked Frameworks and Libraries** 部分中点击 **+**。 + 在 **Linked Frameworks and Libraries** 部分中点击 **+**。 1. Select the system library to link against. - 选择要链接的系统库。 + 选择要链接的系统库。 #### First-party library {:#ios-first-party-library} @@ -294,19 +294,19 @@ use the following instructions: 1. In Xcode, open `Runner.xcworkspace`. - 在 Xcode 中,打开 `Runner.xcworkspace`。 + 在 Xcode 中,打开 `Runner.xcworkspace`。 1. Add the C/C++/Objective-C/Swift source files to the Xcode project. - 将 C/C++/Objective-C/Swift - 源码文件添加到 Xcode 项目中。 + 将 C/C++/Objective-C/Swift + 源码文件添加到 Xcode 项目中。 1. Add the following prefix to the exported symbol declarations to ensure they are visible to Dart: - 将以下前缀添加到导出的 Symbol 符号声明中,以 - 确保它们对 Dart 可见: + 将以下前缀添加到导出的 Symbol 符号声明中,以 + 确保它们对 Dart 可见: **C/C++/Objective-C:** @@ -333,17 +333,17 @@ use the following instructions: 1. If a properly signed `Framework` file is present, open `Runner.xcworkspace`. - 如果存在正确签名的 `Framework` 文件,请打开 `Runner.xcworkspace`。 + 如果存在正确签名的 `Framework` 文件,请打开 `Runner.xcworkspace`。 1. Add the framework file to the **Frameworks, Libraries, and Embedded Content** section of the target in Xcode. - 将 framework 文件添加到 Xcode 中目标下的 **Frameworks, Libraries, and Embedded Content** 部分。 + 将 framework 文件添加到 Xcode 中目标下的 **Frameworks, Libraries, and Embedded Content** 部分。 1. Under the **Embed** column, select **Embed & Sign**. - 在 **Embed** 列下,选择 **Embed & Sign**。 + 在 **Embed** 列下,选择 **Embed & Sign**。 #### Open-source third-party library {:#ios-open-source-third-party-library} @@ -357,11 +357,11 @@ use the following instructions: 1. In your plugin project, open `ios/.podspec`. - 在你的 plugin 项目中,打开 `ios/.podspec`。 + 在你的 plugin 项目中,打开 `ios/.podspec`。 1. Add the native code to the `source_files` field. - 将原生代码添加到 `source_files` 字段。 + 将原生代码添加到 `source_files` 字段。 The native code is then statically linked into the application binary of any app that uses this plugin. @@ -380,12 +380,12 @@ use the following instructions: 1. In your plugin project, open `ios/.podspec`. - 在你的 plugin 项目中,打开 `ios/.podspec`。 + 在你的 plugin 项目中,打开 `ios/.podspec`。 1. Add a `vendored_frameworks` field. See the [CocoaPods example][]. - 添加一个 `vendored_frameworks` 字段。请参阅 [CocoaPods 示例][CocoaPods example]。 + 添加一个 `vendored_frameworks` 字段。请参阅 [CocoaPods 示例][CocoaPods example]。 :::warning @@ -413,11 +413,11 @@ When creating a release build, Xcode strips the symbols. 1. In Xcode, select the **Runner** target, then go to **Build Settings > Strip Style**. - 在 Xcode 中,选择 **Runner** 目标,然后转到 **Build Settings > Strip Style**。 + 在 Xcode 中,选择 **Runner** 目标,然后转到 **Build Settings > Strip Style**。 1. Change from **All Symbols** to **Non-Global Symbols**. - 从 **All Symbols** 更改为 **Non-Global Symbols**。 + 从 **All Symbols** 更改为 **Non-Global Symbols**。 ### macOS @@ -450,19 +450,19 @@ use the following instructions: 1. In Xcode, open `Runner.xcworkspace`. - 在 Xcode 中,打开 `Runner.xcworkspace`。 + 在 Xcode 中,打开 `Runner.xcworkspace`。 1. Select the target platform. - 选择目标平台。 + 选择目标平台。 1. Click **+** in the **Linked Frameworks and Libraries** section. - 在 **Linked Frameworks and Libraries** 部分中点击 **+**。 + 在 **Linked Frameworks and Libraries** 部分中点击 **+**。 1. Select the system library to link against. - 选择要链接的系统库。 + 选择要链接的系统库。 #### First-party library {:#macos-first-party-library} @@ -487,17 +487,17 @@ use the following instructions: 1. In Xcode, open `Runner.xcworkspace`. - 在 Xcode 中,打开 `Runner.xcworkspace`。 + 在 Xcode 中,打开 `Runner.xcworkspace`。 1. Add the C/C++/Objective-C/Swift source files to the Xcode project. - 将 C/C++/Objective-C/Swift 源文件添加到 Xcode 项目中。 + 将 C/C++/Objective-C/Swift 源文件添加到 Xcode 项目中。 1. Add the following prefix to the exported symbol declarations to ensure they are visible to Dart: - 将以下前缀添加到导出的 Symbols 符号声明中,以确保它们对 Dart 可见: + 将以下前缀添加到导出的 Symbols 符号声明中,以确保它们对 Dart 可见: **C/C++/Objective-C:** @@ -523,17 +523,17 @@ use the following instructions: 1. If a properly signed `Framework` file is present, open `Runner.xcworkspace`. - 如果存在正确签名的 `Framework` 文件,请打开 `Runner.xcworkspace`。 + 如果存在正确签名的 `Framework` 文件,请打开 `Runner.xcworkspace`。 1. Add the framework file to the **Frameworks, Libraries, and Embedded Content** section of the target in Xcode. - 将 framework 文件添加到 Xcode 中目标下的 **Frameworks, Libraries, and Embedded Content** 部分。 + 将 framework 文件添加到 Xcode 中目标下的 **Frameworks, Libraries, and Embedded Content** 部分。 1. Under the **Embed** column, select **Embed & Sign**. - 在 **Embed** 列下,选择 **Embed & Sign**。 + 在 **Embed** 列下,选择 **Embed & Sign**。 #### Compiled (dynamic) library, closed source {:#macos-compiled-dynamic-library-closed-source} @@ -548,80 +548,80 @@ use the following instructions: 1. Follow the instructions for Flutter desktop to create a Flutter desktop app. - 按照 Flutter 桌面版的说明创建一个 Flutter 桌面应用。 + 按照 Flutter 桌面版的说明创建一个 Flutter 桌面应用。 1. Open the `yourapp/macos/Runner.xcworkspace` in Xcode. - 在 Xcode 中打开 `yourapp/macos/Runner.xcworkspace`。 + 在 Xcode 中打开 `yourapp/macos/Runner.xcworkspace`。 1. Drag your precompiled library (`libyourlibrary.dylib`) into `Runner/Frameworks`. - 将你的预编译库 (`libyourlibrary.dylib`) 拖到 `Runner/Frameworks` 中。 + 将你的预编译库 (`libyourlibrary.dylib`) 拖到 `Runner/Frameworks` 中。 1. Click `Runner` and go to the `Build Phases` tab. - 点击 `Runner` 并转到 `Build Phases` 选项卡。 + 点击 `Runner` 并转到 `Build Phases` 选项卡。 1. Drag `libyourlibrary.dylib` into the `Copy Bundle Resources` list. - 将 `libyourlibrary.dylib` 拖到 `Copy Bundle Resources` 列表中。 + 将 `libyourlibrary.dylib` 拖到 `Copy Bundle Resources` 列表中。 1. Under `Embed Libraries`, check `Code Sign on Copy`. - 在 `Embed Libraries` 下,勾选 `Code Sign on Copy`。 + 在 `Embed Libraries` 下,勾选 `Code Sign on Copy`。 1. Under `Link Binary With Libraries`, set status to `Optional`. (We use dynamic linking, no need to statically link.) - 在 `Link Binary With Libraries` 下,将状态设置为 `Optional`。(我们使用动态链接,无需静态链接。) + 在 `Link Binary With Libraries` 下,将状态设置为 `Optional`。(我们使用动态链接,无需静态链接。) 1. Click `Runner` and go to the `General` tab. - 点击 `Runner` 并转到 `General` 选项卡。 + 点击 `Runner` 并转到 `General` 选项卡。 1. Drag `libyourlibrary.dylib` into the **Frameworks, Libraries, and Embedded Content** list. - 将 `libyourlibrary.dylib` 拖到 **Frameworks, Libraries, and Embedded Content** 列表中。 + 将 `libyourlibrary.dylib` 拖到 **Frameworks, Libraries, and Embedded Content** 列表中。 1. Select **Embed & Sign**. - 选择 **Embed & Sign**。 + 选择 **Embed & Sign**。 1. Click **Runner** and go to the **Build Settings** tab. - 点击 **Runner** 并转到 **Build Settings** 选项卡。 + 点击 **Runner** 并转到 **Build Settings** 选项卡。 1. In the **Search Paths** section configure the **Library Search Paths** to include the path where `libyourlibrary.dylib` is located. - 在 **Search Paths** 部分中,配置 **Library Search Paths** 以包含 `libyourlibrary.dylib` 所在的路径。 + 在 **Search Paths** 部分中,配置 **Library Search Paths** 以包含 `libyourlibrary.dylib` 所在的路径。 1. Edit `lib/main.dart`. - 编辑 `lib/main.dart`。 + 编辑 `lib/main.dart`。 1. Use `DynamicLibrary.open('libyourlibrary.dylib')` to dynamically link to the symbols. - 使用 `DynamicLibrary.open('libyourlibrary.dylib')` 动态链接到 Symbols 符号。 + 使用 `DynamicLibrary.open('libyourlibrary.dylib')` 动态链接到 Symbols 符号。 1. Call your native function somewhere in a widget. - 在 widget 中的某个地方调用你的原生函数。 + 在 widget 中的某个地方调用你的原生函数。 1. Run `flutter run` and check that your native function gets called. - 运行 `flutter run` 并检查你的原生函数是否被调用。 + 运行 `flutter run` 并检查你的原生函数是否被调用。 1. Run `flutter build macos` to build a self-contained release version of your app. - 运行 `flutter build macos` 来构建一个 - 独立的发布版本的应用。 + 运行 `flutter build macos` 来构建一个 + 独立的发布版本的应用。 [Flutter macOS Desktop]: /platform-integration/macos/building @@ -636,12 +636,12 @@ When creating a release build, Xcode strips the symbols. 1. In Xcode, select the **Runner** target, then go to **Build Settings > Strip Style**. - 在 Xcode 中,选择 **Runner** 目标, - 然后前往 **Build Settings > Strip Style**。 + 在 Xcode 中,选择 **Runner** 目标, + 然后前往 **Build Settings > Strip Style**。 1. Change from **All Symbols** to **Non-Global Symbols**. - 从 **All Symbols** 更改为 **Non-Global Symbols**。 + 从 **All Symbols** 更改为 **Non-Global Symbols**。 ### Android @@ -658,14 +658,14 @@ use the following instructions: 1. Find the desired library in the [Android NDK Native APIs][] list in the Android docs. This lists stable native APIs. - 在 Android 文档的 [Android NDK Native APIs][] - 列表中找到所需的库。此列表包含稳定的原生 API。 + 在 Android 文档的 [Android NDK Native APIs][] + 列表中找到所需的库。此列表包含稳定的原生 API。 1. Load the library using [`DynamicLibrary.open`][]. For example, to load OpenGL ES (v3): - 使用 [`DynamicLibrary.open`][`DynamicLibrary.open`] 加载库。 - 例如,加载 OpenGL ES (v3): + 使用 [`DynamicLibrary.open`][`DynamicLibrary.open`] 加载库。 + 例如,加载 OpenGL ES (v3): ```dart DynamicLibrary.open('libGLES_v3.so'); @@ -718,15 +718,15 @@ use the following instructions: 1. Open the `android/build.gradle` file for your project. - 打开你项目的 `android/build.gradle` 文件。 + 打开你项目的 `android/build.gradle` 文件。 1. Add the AAR artifact as a dependency. **Don't** include the artifact in your Flutter package. Instead, it should be downloaded from a repository, such as Maven Central. - 将 AAR artifact 添加为依赖项。 - **不要** 将 artifact 包含在你的 Flutter package 中。 - 相反,它应该从仓库(例如 Maven Central)下载。 + 将 AAR artifact 添加为依赖项。 + **不要** 将 artifact 包含在你的 Flutter package 中。 + 相反,它应该从仓库(例如 Maven Central)下载。 #### Android APK size (shared object compression)