鸿蒙Next如何调用mnn编译的so库

在鸿蒙Next开发中,如何正确调用由MNN框架编译生成的so库?目前尝试在Native层通过System.loadLibrary加载so文件时遇到报错,提示找不到符号或库版本不兼容。具体环境:DevEco Studio 3.1,MNN 2.6.0交叉编译的arm64-v8a库。是否需要特殊配置CMakeLists.txt或修改build.gradle?求完整集成流程和常见问题解决方案。

2 回复

鸿蒙Next调用MNN的so库?简单!先确保so库放对位置,然后配置CMakeLists.txt链接库,最后在代码里System.loadLibrary("MNN")加载。记得检查ABI兼容性,别让so库“迷路”哦!

更多关于鸿蒙Next如何调用mnn编译的so库的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在鸿蒙Next中调用MNN编译的.so库,主要通过Native API(ArkTS的FFI机制)实现。以下是关键步骤和示例代码:

1. 准备.so库文件

  • 将MNN编译生成的.so文件(如 libMNN.so)放入项目 src/main/cpp/types 目录中。
  • build-profile.json5 中配置依赖:
    "externalNativeOptions": {
      "path": "./src/main/cpp/CMakeLists.txt"
    }
    

2. 编写CMakeLists.txt

src/main/cpp/CMakeLists.txt 中链接库:

add_library(mnntest SHARED mnn_test.cpp)
target_link_libraries(mnntest PUBLIC libMNN.so)

3. 创建Native接口

src/main/cpp/mnn_test.cpp 中实现JNI函数:

#include <jni.h>
#include "MNN/Interpreter.hpp"

extern "C"
JNIEXPORT jlong JNICALL
Java_com_example_MNNHelper_initMNN(JNIEnv *env, jobject thiz, jstring model_path) {
    const char *path = env->GetStringUTFChars(model_path, nullptr);
    auto interpreter = MNN::Interpreter::createFromFile(path);
    env->ReleaseStringUTFChars(model_path, path);
    return reinterpret_cast<jlong>(interpreter);
}

4. ArkTS层调用

在ArkTS中通过FFI加载库并声明Native方法:

import { ohos } from '@kit.FFIKit';

const libName = 'libmnntest.so';
const mnnLib = ohos.dlopen(libName);

// 定义Native方法接口
const initMNN = mnnLib.getSymbol('Java_com_example_MNNHelper_initMNN');
let modelPtr = initMNN("model.mnn"); // 传入模型路径

关键注意事项:

  1. ABI兼容性:确保MNN的.so库与鸿蒙设备的架构(arm64-v8a/armeabi-v7a)匹配。
  2. 内存管理:Native返回的指针需在ArkTS中妥善管理,避免内存泄漏。
  3. 线程安全:MNN推理建议在子线程执行,避免阻塞UI。

通过以上步骤,即可在鸿蒙Next中完成MNN模型的加载与调用。实际使用时需根据MNN的API进一步实现前向推理、内存释放等逻辑。

回到顶部