- Home /
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 + "\n" + 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.
Answer by Arshia001 · Dec 02, 2015 at 04:23 AM
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.
Hi, can you share how you solved this issue? We are running into the same problem while trying to link OpenCV natively
For people having trouble with this, you'll need to add a public function to your plugin like so:
Java:
public static void loadLibc() {
System.loadLibrary("c");
}
And then back in Unity you'll need to call it:
private void importLibc() {
AndroidJavaClass plugin = new AndroidJavaClass("PluginClass");
plugin.CallStatic("loadLibc");
}
In my example, I was getting the error that it couldn't find the library "libc". So I had to call loadLibrary
on "c".
Edit: This does not work.
Answer by CAMOBAP · Dec 02, 2015 at 03:17 AM
You may inspect your library dependencies first, like described below http://stackoverflow.com/questions/6242761/how-do-i-find-the-direct-shared-object-dependencies-of-a-linux-elf-binary
Answer by heyGlo · Jun 17, 2015 at 03:28 PM
try to add libopencv_java.so into the your unity project: ../Assets/Plugins/Android/