通过查阅flutter官方文档,我们惊喜地发现flutter官方提供了一个dart:ffi(Foreign Function Interface: 外部功能接口)库来调用本地的 C API。下面我们就一起来看看如何将C代码集成到flutter项目中并且调用其中的方法。
安卓为例:创建一个 android/CMakeLists.txt 文件用来定义如何编译源文件,位置随意,可以在android目录下也可以在android/app或android/app/main/src/cpp都行,只要在后面的gradle添加正确路径即可,这里以android/app目录下为例。
cmake_minimum_required(VERSION 3.4.1) # for example # find_library( # Defines the name of the path variable that stores the # # location of the NDK library. # log-lib # # Specifies the name of the NDK library that # # CMake needs to locate. # log ) add_library(native-lib # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). app/src/main/cpp/native-lib.cpp) target_link_libraries( native-lib log )
添加一个 externalNativeBuild 到你的 android/build.gradle 文件中。示例如下
plugins { id "com.android.application" id "kotlin-android" id "dev.flutter.flutter-gradle-plugin" } def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } //flutter toast需要最低21版本 flutter.minSdkVersion = 21 android { namespace "com.lee.demo.flutter_demo" compileSdk flutter.compileSdkVersion ndkVersion flutter.ndkVersion compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } sourceSets { main.java.srcDirs += 'src/main/kotlin' } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.lee.demo.flutter_demo" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdkVersion flutter.minSdkVersion targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName } buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } } externalNativeBuild { // Encapsulates your CMake build configurations. cmake { // Provides a relative path to your CMake build script. path "../CMakeLists.txt" } } } flutter { source '../..' } dependencies {}
这样最终会生成一个动态链接库.so文件
使用 FFI 库绑定本地代码
接下来,我们需要在 lib/my_native.dart文件中编写一些代码,将C代码函数转换成Dart代码方法。
import 'dart:ffi'; import 'dart:io'; class NativeLib { //函数声明 late final int Function(int x, int y) funcAdd; //初始化 NativeLib() { final DynamicLibrary nativeLib = Platform.isAndroid ? DynamicLibrary.open('libnative-lib.so') : DynamicLibrary.process(); //静态链接中的符号可以使用 DynamicLibrary.executable //或 DynamicLibrary.process 来加载。 //动态链接库在 Dart 中可以通过 DynamicLibrary.open 加载。 //函数定义 funcAdd = nativeLib .lookup<NativeFunction<Int32 Function(Int32, Int32)>>('native_add') .asFunction(); } }
不同平台加载库方式也不同,以下作为参考
const String _libName = 'hello'; /// The dynamic library in which the symbols for [HelloBindings] can be found. final DynamicLibrary _dylib = () { if (Platform.isMacOS || Platform.isIOS) { return DynamicLibrary.open('$_libName.framework/$_libName'); } if (Platform.isAndroid || Platform.isLinux) { return DynamicLibrary.open('lib$_libName.so'); } if (Platform.isWindows) { return DynamicLibrary.open('$_libName.dll'); } throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}'); }(); /// The bindings to the native functions in [_dylib]. final HelloBindings _bindings = HelloBindings(_dylib); int sum(int a, int b) => _bindings.sum(a, b);
也可以通过以下命令生成dart使用文件
flutter pub run ffigen --config ffigen.yaml
使用非常简单
void main() { debugPrint('native add:8+9=${NativeLib().funcAdd(8, 9)}'); runApp(const MyApp()); }
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2305
- 用户1336
- 访客11412506
每日一句
Move forward to keep life balanced.
人生如骑行,前进即平衡。
人生如骑行,前进即平衡。
Android开源刮刮卡库ScratchCardLayout使用教程
使用VS Code断点调试Vue代码
p2p通信,打洞技术,穿越NAT的实现(附NAT环境检测工具)
NDK19c Clang交叉编译arm64-v8a、armeabi-v7a架构下Boost
Android更新速度越来越快吗?
Vue父组件传对象给子组件
如何精简化Xposed
C++获取Windows 10的版本号
diskgenius 保存分区表时出现错误 代码00000032方法解决
亲测!虚拟机VirtualBox安装MAC OS 10.12图文教程
快速入门-如何在Java上使用Redis
CreateProcessW要注意的细节问题
关于iOS最常见的15个问题
新会员