通过查阅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)
站点信息
- 文章2315
- 用户1336
- 访客11886327
每日一句
Love is seeing, and it is space.
爱是看见,也是空间。
爱是看见,也是空间。