简体   繁体   中英

Native Android library in Unity throws DllNotFound exception

I have written a chess library in C++ and I have compiled it for Windows (32-bit and 64-bit) and Android (x86 and armebi-v7).

My Windows build works completely correct, But when I build it for Android and when I run the game, I receive the following exception on my adb logcat -s Unity :

11-23 16:39:37.278 22335 22352 I Unity   : DllNotFoundException: MatinChess
11-23 16:39:37.278 22335 22352 I Unity   :   at (wrapper managed-to-native) MatinChess.Net.ExternMethods:Initialize ()
11-23 16:39:37.278 22335 22352 I Unity   :   at MatinChess.Net.MatinChess..ctor () [0x00000] in <filename unknown>:0
11-23 16:39:37.278 22335 22352 I Unity   :   at Model.Awake () [0x00000] in <filename unknown>:0

And when I unzip my apk file I have:

lib
|_ armeabi-v7a
|  |_ libmain.so
|  |_ libMatinChess.so
|  |_ libmono.so
|  |_ libunity.so
|_ x86
   |_ libmain.so
   |_ libMatinChess.so
   |_ libmono.so
   |_ libunity.so

Here are my settings and scripts:

Based on here and here , I have created Plugins folder in my Assets and placed my libraries like this:

Plugins
|_ Android
|  |_ libs
|     |_ armeabi-v7a
|     |  |_ libMatinChess.so
|     |_ x86
|        |_ libMatinChess.so
|_ x64
|  |_ MatinChess.dll
|_ x86
   |_ MatinChess.dll

And I got sure that the Platform Settings in my Inspector is configured correctly.

I have used my library in my scripts and based on here and here , instead of using libMatinChess.so for Android, I have not used lib at the beggining and .so at the end. So it is like this:

class ExternMethods
{
#if UNITY_ANDROID
    const string dll = "MatinChess";
#else
    const string dll = "MatinChess.dll";
#endif

    [DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
    public extern static PlayState CheckState();

    [DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
    public extern static void Initialize();

    //
    // other extern methods
    //
}

So when I build my Unity game for Windows, it works correctly. In order to make it work in Editor, I have followed this link and I have written the folowing script:

public class Model : MonoBehaviour
{    
    void Awake()
    {
#if UNITY_EDITOR_32
        var dllPath = Application.dataPath + Path.DirectorySeparatorChar + "Plugins" + Path.DirectorySeparatorChar + "x32";
#elif UNITY_EDITOR_64
        var dllPath = Application.dataPath + Path.DirectorySeparatorChar + "Plugins" + Path.DirectorySeparatorChar + "x64";
#else // Player
        var dllPath = Application.dataPath + Path.DirectorySeparatorChar + "Plugins";
#endif
        var currentPath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process);
        if (currentPath != null && currentPath.Contains(dllPath) == false)
            Environment.SetEnvironmentVariable("PATH", currentPath + Path.PathSeparator + dllPath, EnvironmentVariableTarget.Process);
    }
}

So it works on Unity Editor as well.

The method MatinChess.Net.ExternMethods.Initialize may be called before Environment.SetEnvironmentVariable("PATH",...) , which leads to a DllNotFoundException.

Try printing a log message before you call MatinChess.Net.ExternMethods.Initialize and Environment.SetEnvironmentVariable . Then you can inspect the calling order of these methods.

Add if that's the cause, moving Environment.SetEnvironmentVariable("PATH",...) to the static initializer of MatinChess.Net.ExternMethods can possibly solve your problem.

Edit:
Try printing the PATH after you setting it, the method may failed to set it.

Edit:
Just a guess.. the android shared lib searching path should be LD_LIBRARY_PATH instead of PATH . Try setting that instead. I'm not sure if Unity3D has handled this.

Edit:
Not including all the library dependencies aside your libMatinChess.so is a possible cause. Some infomation here .

The above are all I can think of now.

Check that you are actually exporting a valid .so file with the proper symbols.

Also check that you have included all library dependencies of your libMatinChess.so which may include your C runtime at times. Try linking statically with the standard library.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM