当前位置:   article > 正文

在flutter项目集成C/C++并生成符合架构的SO文件_flutter c++

flutter c++

本方案采用NDK+Cmake在flutter实现,建议各位先看图片,我是先截图后面才补充的代码内容,按照顺序看图就好,然后具体代码只是一个参考,主要是为了防止图片看不清被压缩啥的,图片里面的描述已经很清晰了,我的项目文件目录结构在最后也都加上了注释,希望可以帮助到你们
 

1.首先创建C/C++文件

放置到项目任意地址,当然了谷歌官方建议我们丢到以下这个目录

  1. 源码
  2. android\app\src\main\cpp
  3. 头文件
  4. android\app\src\main\cpp\include
2.实现CMake
  1. cmake_minimum_required(VERSION 3.4.1)
  2. #设置生成的so动态库最后输出的路径
  3. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI})
  4. #.h文件目录
  5. include_directories(
  6. ${CMAKE_SOURCE_DIR}/cpp/include #h文件目录
  7. )
  8. add_library( # Sets the name of the library.
  9. helloworld #c/cpp代码将要编译成为so库的名称,java代码加载库文件要用这个名称
  10. SHARED #动态库
  11. cpp/helloworld.c #cpp代码文件路径 可以在下面接着随意添加c、c++文件
  12. # src/main/cpp/cpp_test.cpp
  13. # src/main/jni/ndkdemo-lib.c #参见step 5
  14. # src/main/jni/ndkdemo-lib.cpp #参见step 5
  15. )
  16. find_library( #调用系统库
  17. log-lib #打印用
  18. log)
  19. target_link_libraries( # Specifies the target library.
  20. helloworld
  21. ${log-lib})

3.配置Gradle

主要是修改指向NDK的目录和版本号,调用Cmake,NDK要预先在Android studio 下载配置好

  1. plugins {
  2. id "com.android.application"
  3. id "kotlin-android"
  4. id "dev.flutter.flutter-gradle-plugin"
  5. }
  6. def localProperties = new Properties()
  7. def localPropertiesFile = rootProject.file('local.properties')
  8. if (localPropertiesFile.exists()) {
  9. localPropertiesFile.withReader('UTF-8') { reader ->
  10. localProperties.load(reader)
  11. }
  12. }
  13. def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
  14. if (flutterVersionCode == null) {
  15. flutterVersionCode = '1'
  16. }
  17. def flutterVersionName = localProperties.getProperty('flutter.versionName')
  18. if (flutterVersionName == null) {
  19. flutterVersionName = '1.0'
  20. }
  21. android {
  22. namespace "com.example.bledataupload"
  23. compileSdkVersion 34
  24. // ndkVersion flutter.ndkVersion
  25. ndkVersion "26.1.10909125"
  26. compileOptions {
  27. sourceCompatibility JavaVersion.VERSION_1_8
  28. targetCompatibility JavaVersion.VERSION_1_8
  29. }
  30. kotlinOptions {
  31. jvmTarget = '1.8'
  32. }
  33. sourceSets {
  34. main.java.srcDirs += 'src/main/kotlin'
  35. }
  36. defaultConfig {
  37. // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
  38. applicationId "com.example.bledataupload"
  39. // You can update the following values to match your application needs.
  40. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
  41. // minSdkVersion flutter.minSdkVersion
  42. minSdkVersion 24
  43. targetSdkVersion flutter.targetSdkVersion
  44. versionCode flutterVersionCode.toInteger()
  45. versionName flutterVersionName
  46. }
  47. buildTypes {
  48. release {
  49. // TODO: Add your own signing config for the release build.
  50. // Signing with the debug keys for now, so `flutter run --release` works.
  51. signingConfig signingConfigs.debug
  52. }
  53. }
  54. // packagingOptions {
  55. // // 确保app与asr_plugin都依赖的libflutter.so merge时不冲突@https://github.com/card-io/card.io-Android-SDK/issues/186#issuecomment-427552552
  56. // pickFirst 'lib/x86_64/libflutter.so'
  57. // pickFirst 'lib/x86/libflutter.so'
  58. // pickFirst 'lib/arm64-v8a/libflutter.so'
  59. // }
  60. externalNativeBuild {
  61. // Encapsulates your CMake build configurations.
  62. cmake {
  63. // Provides a relative path to your CMake build script.
  64. path "CMakeLists.txt"
  65. }
  66. }
  67. }
  68. flutter {
  69. source '../..'
  70. }
  71. dependencies {
  72. implementation fileTree(include: ['*.jar'], dir: 'libs')
  73. // implementation files('libs/bdasr_V3_20210628_cfe8c44.jar')
  74. // implementation files('libs/Hello.jar')
  75. }

4.目录和结果展示

PS:可能会有用的内容
  1. sdk.dir=D:\\Program Files\\Android\\sdk
  2. # ndk.dir=D:\\Program Files\\Android\\sdk\\ndk\\26.1.10909125
  3. flutter.sdk=D:\\flutter
  4. flutter.buildMode=debug
  5. flutter.versionName=0.1.0

最后特别感谢在此期间所有帮助到我的博客和文章,由于参考数量太多,就不一一列举出来了(主要是参考太多了,很多没有意义的文章更多.....),官方案例写的真的是一言难尽,本身我也是第一次接触,结果好多步骤跨越性那么大,毫无参考意义,故,有此文章的诞生


哦对了,我只是生成了,还没用起来,不过良好的开端是有了,不是吗?

/**************************************************手动分割线*********************************************/

5.使用生成的库

首先你得引入一个三方的库,

import 'package:ffi/ffi.dart';

否则你找不到下面两个内容

  1.  final getdata = getstr().cast<Utf8>();
  2.  debugPrint('${getdata.toDartString()}');
  3. // Utf8 & toDartString 不在官方的库里面

6. 完整的使用代码

 
6.1 首先申明一些必要的函数,必须是静态的,放在类外,不要丢在类里面,全局的

  1. // FFI signature of the hello_world C function
  2. typedef hello_world_func = ffi.Void Function();
  3. typedef getstr_func = ffi.Pointer<ffi.Int8> Function();

6.2 调用

  1. onTap: () async {
  2. debugPrint('当前路径 ${Directory.current.path}');
  3. ffi.DynamicLibrary dylib;
  4. // Open the dynamic library
  5. if (Platform.isWindows) {
  6. dylib = ffi.DynamicLibrary.open('libhelloworld.dll');
  7. } else if (Platform.isAndroid) {
  8. dylib = ffi.DynamicLibrary.open('libhelloworld.so');
  9. } else if (Platform.isIOS) {
  10. dylib = ffi.DynamicLibrary.open('libhelloworld.dylib');
  11. } else {
  12. debugPrint('平台异常');
  13. return;
  14. }
  15. debugPrint('打开');
  16. // Look up the C function 'hello_world'
  17. void Function() hello = dylib
  18. .lookup<ffi.NativeFunction<hello_world_func>>('hello_world')
  19. .asFunction();
  20. // Call the function
  21. hello();
  22. // Look up the C function 'hello_world'
  23. getstr_func getstr = dylib
  24. .lookup<ffi.NativeFunction<getstr_func>>('getstr')
  25. .asFunction();
  26. debugPrint('$getstr');
  27. // Call the function
  28. final getdata = getstr().cast<Utf8>();
  29. debugPrint(getdata.toDartString());
  30. },

7. 结束
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/976814
推荐阅读
相关标签
  

闽ICP备14008679号