You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

成功编译Unity Android适配的OpenCV SO库,为何仍报DllNotFoundException?

解决Unity Android调用带OpenCV的SO库出现DllNotFoundException的问题

核心问题分析

纯Native SO能正常加载,但集成OpenCV后加载失败,问题集中在OpenCV依赖库打包、函数导出格式或ABI/NDK兼容性上,以下是针对性解决步骤:


1. 手动打包OpenCV依赖库

你的SO依赖libopencv_java4.so,Unity不会自动识别并打包该依赖库,需手动将其复制到Unity项目的Plugins/Android/arm64-v8a目录下,与libOpenCVwithUnityAndroid.so放在同一层级。

2. 严格匹配ABI架构

  • 验证SO架构:用NDK自带工具检查你的SO是否为ARM64-v8a架构:
    # 进入NDK的toolchains/llvm/prebuilt/windows-x86_64/bin目录执行
    aarch64-linux-android-readelf -h libOpenCVwithUnityAndroid.so
    
    查看输出的Machine字段,必须为AArch64。
  • 确保使用的OpenCV库也是arm64-v8a版本,禁止混用其他架构库。

3. 修正C++函数导出格式

当前类成员函数即使在extern "C"块中,仍会被C++名字修饰改变函数名,导致Unity无法匹配。改成全局函数并显式声明可见性:

#include "OpenCVwithUnityAndroid.h"
#include "opencv2/core.hpp"

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "TestSharedObject", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "TestSharedObject", __VA_ARGS__))

struct Color32
{
    uchar red;
    uchar green;
    uchar blue;
    uchar alpha;
};

extern "C" __attribute__((visibility("default"))) const char* getPlatformABI()
{
#if defined(__arm__)
    #if defined(__ARM_ARCH_7A__)
        #if defined(__ARM_NEON__)
            #define ABI "armeabi-v7a/NEON"
        #else
            #define ABI "armeabi-v7a"
        #endif
    #else
        #define ABI "armeabi"
    #endif
#elif defined(__i386__)
    #define ABI "x86"
#elif defined(__aarch64__)
    #define ABI "arm64-v8a"
#else
    #define ABI "unknown"
#endif
    return "This native library is compiled with ABI: %s" ABI ".";
}

extern "C" __attribute__((visibility("default"))) void FlipImage(Color32** rawImage1, int width1, int height1) {
    using namespace cv;
    Mat Image(height1, width1, CV_8UC4, *rawImage1);
    flip(Image, Image, -1);
}

Unity侧的DllImport要对应全局函数名:

[DllImport("OpenCVwithUnityAndroid")]
private static extern string getPlatformABI();

[DllImport("OpenCVwithUnityAndroid")]
private static extern void FlipImage(ref Color32[] rawImage, int width, int height);

4. 统一NDK版本与STL设置

  • 使用Unity 2021.3.22推荐的NDK版本(r21d)编译SO,避免版本不兼容导致底层库冲突。
  • 编译SO时的STL设置保持为LLVM libc++ c++_static,与Unity默认STL一致,禁止使用shared版本。

5. 调整Unity打包配置

  • 在Player Settings > Android > Other Settings中:
    • 脚本后端选择IL2CPP
    • 目标架构只勾选ARM64,取消其他架构选项
  • 若问题仍存在,勾选Publishing Settings中的Custom Main Gradle Template,打开mainTemplate.gradle,确保添加本地库打包配置(如无则补充):
    android {
        sourceSets {
            main {
                jniLibs.srcDirs = ['libs']
            }
        }
    }
    

6. 日志定位具体错误

用Android Studio的Logcat过滤UnsatisfiedLinkError或DllNotFoundException,日志会明确提示错误原因:

  • 若提示libopencv_java4.so not found:说明依赖库未正确打包
  • 若提示cannot find symbol FlipImage:说明函数导出格式有误

内容的提问来源于stack exchange,提问作者Boosil-guy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 22:38:10