Flutter 使用C++代码 或使用.so文件

545 阅读2分钟

Flutter 编译.cpp 并生成且调用so动态库

先讲一下流程:

  1. 在正确的地方放置 .so 文件
  2. 编写 dart 代码调用 native 函数
  3. 在 dart 代码中调用 dart 映射的函数

一、创建C++代码:

  1. 首先在工程中android/app/目录下新建CMakeLists.txt
cmake_minimum_required(VERSION 3.16.5)  # 版本根据自己的需要进行修改

add_library(
        # 编译打包出来的lib文件名称,以下打包出来为:libnative_add.so
        native_add

        # 动态库使用:SHARED、静态库使用:STATIC
        SHARED

        # 源文件可以放在别的地方
        ding.cpp 
)

2.在工程中android/app/目录下创建ding.cpp

#include <iostream>
extern "C" {
    int32_t add(int32_t a, int32_t b) {
        return a + b;
    }
       const char* addstr(const char* a, const char* b) {
        // 计算拼接后的字符串的长度
        size_t resultLength = strlen(a) + strlen(b) + 1;

        // 分配足够的内存来存储拼接后的字符串
        char* result = (char*)malloc(resultLength);

        // 将字符串a复制到结果字符串
        strcpy(result, a);

        // 追加字符串b到结果字符串
        strcat(result, b);

        return result;
    }
}

3.修改android/app/build.gradle文件 在最后一行添加即可

android {
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}

运行项目 so文件会存放在 ‘项目名/build/app/intermediates/merged_native_libs/debug/out/lib/’

二、加载.so文件并创建映射函数

1.在项目lib中创建native.dart 需要注意,Flutter官方库不支持Pointer《Utf8》 需要手动引入

dart pub add ffi 引入完成后即可获取返回的char
// TODO Implement this library.
// ffi 加载动态库,并映射 native 函数
import 'dart:ffi';
import 'dart:io';
import 'package:ffi/ffi.dart';

final addLib = Platform.isAndroid
    ? DynamicLibrary.open('libnative_add.so')
    : DynamicLibrary.process();
    
//查找函数 返回值是int
final addFunc =
    addLib.lookupFunction<Int32 Function(Int32, Int32), int Function(int, int)>(
        'add');

//查找函数 返回值是String
//这里的Pointer<Utf8>用于表示字符串的指针类型,对应于 C/C++ 中的 const char* 类型。
//toNativeUtf8():将 Dart 字符串转换为 UTF-8 编码的 C 字符串,并返回 Pointer<Utf8>。
// toDartString():将返回的 Pointer<Utf8> 转换为 Dart 字符串。
final addFunc_str = addLib.lookupFunction<
    Pointer<Utf8> Function(Pointer<Utf8>, Pointer<Utf8>),
    Pointer<Utf8> Function(Pointer<Utf8>, Pointer<Utf8>)>('addstr');

String addStr(String a, String b) {
  final ptrA = a.toNativeUtf8();
  final ptrB = b.toNativeUtf8();

  final resultPtr = addFunc_str(ptrA, ptrB);
  final result = resultPtr.toDartString();

  malloc.free(ptrA);
  malloc.free(ptrB);
  malloc.free(resultPtr);

  return result;
}

2.在需要的地方来调用

int result = addFunc(1, 2);
String result_str = addStr('a', 'b');