CMakeLists生成动态库.so和静态库.a

一、下载NDK CMake

  • NDK : 26.2.11394342 或 23.1.7779620

  • CMake : 3.22.1

二、新建android\app\CMakeLists.txt

文件CMakeLists.txt内容

复制代码
cmake_minimum_required(VERSION 3.4.1)`
`#mker为项目名称`
`project('mker')`

`#设置生成的so动态库最后输出的路径`
`set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI})`

`#生成动态库.so`
`add_library(`
`#c/cpp代码将要编译成为so库的名称,dart代码加载库文件要用这个名称`
`        native_lib `
        
`        SHARED #动态库`
`#cpp代码文件路径 可以在下面接着随意添加c、c++文件`
`        cpp/native_lib.cpp )`
 
` #生成静态库.a`
` add_library(`
`        #静态库.a的名称`
`        mystatic`

`        STATIC #静态库`
`        #cpp代码文件路径 可以在下面接着随意添加c、c++文件`
`        cpp/native_lib.cpp )`
 
`

三、app/build.gradle配置

复制代码
    defaultConfig {`
`。。。。。。`
`//新增`
`        externalNativeBuild {`
`            cmake {`
`                targets 'mystatic','native_lib'`
`            }`
`// > [CXX1201] ABIs [armeabi] are not supported for platform. Supported ABIs are [arm64-v8a, armeabi-v7a, x86, x86_64].`
`//            ndk {`
`//                abiFilters 'x86_64','x86','arm64-v8a', 'armeabi-v7a'`
`//            }`
`        }`

`    }`

` //新增:编译自己的CMake进项目`
`    externalNativeBuild {`
`        // Encapsulates your CMake build configurations.`
`        cmake {`
`            path "../CMakeLists.txt"`
`        }`
`    }`
    
`

四、放c++代码:/android/app/cpp/native_lib.cpp

复制代码
#include <stdint.h>`
`#include <cstring>`
`extern "C" {`
`__attribute__((visibility("default"))) __attribute__((used))`
`int32_t native_add(int32_t x, int32_t y) {`
`    return x + y;`
`}`
`__attribute__((visibility("default"))) __attribute__((used))`
`int32_t native_add2(int32_t x, int32_t y) {`
`    return x + y;`
`}`
`__attribute__((visibility("default"))) __attribute__((used))`
`char* concat(const char* str1, const char* str2) {`
`    int len1 = strlen(str1);`
`    int len2 = strlen(str2);`
`    char* result = new char[len1 + len2 + 1];`
`    strcpy(result, str1);`
`    strcat(result, str2);`
`    return result;`
`}`
`}`


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

五、生成动态库.so和静态库.a

项目根目录下执行命令:flutter build apk后app文件夹下会自动生成libs文件夹,里面放的是不同cpu下的.so文件

.a存放的位置:android/app/.cxx/RelWithDebInfo/5p5v2i3r/arm64-v8a/libmystatic.a

注:生成的.a文件好像不能使用,通过命令行lipo -info xxx.a 查不出cpu架构类型

六、动态库.so验证:

1.pubspec.yaml文件下添加依赖 ffi: ^2.1.2
2.项目lib文件夹下放native_add.dart
复制代码
import 'dart:ffi' as ffi;`
`import 'dart:ffi';`
`import 'dart:io'; // For Platform.isX`

`import 'package:ffi/ffi.dart';`

`final DynamicLibrary nativeAddLib = Platform.isAndroid`
`    ? DynamicLibrary.open("libnative_lib.so")`
`    : DynamicLibrary.process();`

`final int Function(int x, int y) nativeAdd = nativeAddLib`
`    .lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_add")`
`    .asFunction();`

`final int Function(int x, int y) nativeAdd2 = nativeAddLib`
`    .lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_add2")`
`    .asFunction();`

`final int Function(int x, int y) nativeAdd3 = nativeAddLib`
`    .lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_add3")`
`    .asFunction();`

`typedef A2 = Pointer<Utf8> Function(ffi.Pointer<Utf8>, ffi.Pointer<Utf8>);`

`String concatStr(String str1, String str2) {`
`  final privateKeyPtr = str1.toNativeUtf8();`
`  final hexCidMessagePtr = str2.toNativeUtf8();`
`  final concat =`
`      nativeAddLib.lookup<ffi.NativeFunction<A2>>('concat').asFunction<A2>();`
`  return concat(privateKeyPtr, hexCidMessagePtr).toDartString();`
`}`

`bool isExistSymbol(String symbol) {`
`  final isOk = nativeAddLib.providesSymbol(symbol);`
`  return isOk;`
`}`

`
3.flutter调用.so里的方法
复制代码
 int result = nativeAdd(1, 2);`
`    int result2 = nativeAdd2(1, 2);`
`    int result3 = nativeAdd3(1, 2);`
`    print(`
        `'-------------------------result:$result---result2:$result2---result3:$result3');`
`