Flutter FFI 插件库开发

FFI plugin 插件库创建命令

flutter create --org com.cnht.flutter.hello --template=plugin_ffi --platforms=android,ios,macos,windows hello

使用–template=plugin_ffi可以创建一个ffi plugin,此处是通过命令行生产ffi接口,如果自定义接口,可以参考文末链接,制作ffi接口。

这种方式是dart依赖c源码方式提供插件库,不用预先编译动态链接库放到插件工程,通过CMake编译生成各个Native平台的动态链接库,源码都在src目录下管理。

ios和macos的Classes目录下hello.c,通过include引用src目录下的源码,源码放在一个目录方便维护。

FFI plugin 插件库代码结构


FFI plugin 调用Native构建方式

  • 对于Android:通过Gradle调用Android NDK为原生构建。
    • 参考.android/build.gradle中的配置
  • 对于iOS、MacOS:通过Xcode CocoaPods构建
    • 参考.ios/hello.podspec中的配置
    • 参考.macos/hello.podspec中的配置
  • 对于Linux、Windows:通过CMake构建
    • 参考.linux/CMakeLists.txt中的配置
    • 参考.windows/CMakeLists.txt中的配置

例如运行Android时,通过gradle调用CMake生成libhello.so,然后再把so文件打包到hello-debug.aar内,就生成了一个完整的Android AAR库,可以给Android项目使用。

其他问题

FFI 库只能与 C 符号绑定

因此在 C++ 中,这些符号添加 extern C 标记。还应该添加属性来表明符号是需要被 Dart 引用的,以防止链接器在优化链接时会丢弃符号。

例如,创建一个 C++ 文件 native_add.cpp

#include <stdint.h>

extern "C" __attribute__((visibility("default"))) __attribute__((used))
int32_t native_add(int32_t x, int32_t y) {
return x + y;
}

CMakeList文件内指定Language

目前在生成FFI库时,碰到当指定LANGUAGES C会影响Android CMake编译,改成LANGUAGES CXX运行正常。

project(xxx_library VERSION 0.0.1 LANGUAGES CXX)
# project(xxx_library VERSION 0.0.1 LANGUAGES C)

参考

  • Flutter Packages 的开发和提交
  • 使用 dart:ffi 与 C 进行交互
  • Android 上使用 dart:ffi 调用本地代码
  • 在 iOS 中使用 dart:ffi 调用本地代码
  • 在 macOS 中使用 dart:ffi 调用本地代码
  • Dart FFI Samples