Why does Unity fail to load android native libraries when linked against OpenCV?

The title says it all. I’m using NDK to build a native library for use with Unity (the game engine, not the Ubuntu shell). I already have much of the code in place and it works on my Xperia Z Ultra which runs Android 4.4.4. However, recently I sent the app to some other people to test on their phones, and it worked on none of their phones. They were using Android 4.0 and 4.1, so I tried running the app on my own Android 4.0.4 device (an old Xperia Mini Pro) and had the same problem. After much narrowing down, I’ve found out that the root of the problem is including OpenCV in the build, even if it’s not referenced at all.

Here’s the code I have now. First, the simplest CPP file you’ve seen:

//Test.cpp:
extern "C"
{
    int Test(int a, int b)
    {
        return a + b;
    }
}

Note how it doesn’t even include anything from OpenCV. The makefile (or whatever it’s called in the context of NDK, I’m mostly a Windows/Visual Studio person) is:

#Android.mk:
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

#---------------------------
#note: if I comment these lines out, the library works just fine.
#if I don't, it won't load at all.
#---------------------------
OPENCV_PACKAGE_DIR := D:\Eclipse\OpenCVAndroid\OpenCV-2.4.9-android-sdk
include $(OPENCV_PACKAGE_DIR)/sdk/native/jni/OpenCV.mk

LOCAL_MODULE    := Test
LOCAL_SRC_FILES := Test.cpp

include $(BUILD_SHARED_LIBRARY)

Building this project gives me a “libTest.so” file. I put this into my Unity project, at Assets/Plugins/Android/ (I’ve also tried putting it in Plugins/Android/libs/armeabi-v7a/, no luck). I also have a script inside unity which invokes the library:

//TestNative.cs:
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;

public class TestNative : MonoBehaviour
{
    [DllImport("Test")]
    public static extern int Test(int a, int b);

    void OnGUI()
    {
        try
        {
            GUI.Label(new Rect(0, 0, 100, 100), "2 + 3 = " + Test(2, 3));
        }
        catch (System.Exception e)
        {
            GUI.Label(new Rect(0, 0, 600, 400), e.GetType().ToString() + " " + e.Message + "

" + e.StackTrace);
}
}
}

When I run this on my Z Ultra, it works just fine. When I run it on the Mini Pro, it fails with the exception “DllNotFoundException: Test”. I’ve checked logcat for errors, and this is what it says:

01-06 06:46:27.660: D/dalvikvm(11135): Trying to load lib /mnt/asec/com.cet.sna2-2/lib/libTest.so 0x2bb86638
01-06 06:46:27.660: D/dalvikvm(11135): Trying to load lib /mnt/asec/com.cet.sna2-2/lib/libTest.so 0x2bb86638
01-06 06:46:27.660: E/Unity(11135): Unable to find Test

It doesn’t say anything else, it just fails. The fact that it works on 4.4.4 makes me think it might have something to do with build configurations or something like that, but I can’t figure out what it is. Any ideas? Thanks.

Sorry for never updating this question until now. The problem was that Android was not loading the libraries in the correct order. What I did to solve it was to manually load the libraries before they were referenced using Unity’s AndroidJavaObject to make loadLibrary calls and load them in correct order.

You may inspect your library dependencies first, like described below

try to add libopencv_java.so into the your unity project: …/Assets/Plugins/Android/