Dynamic C++ library not found (DllNotFoundException) by C# external method on Android

Hi. I am having trouble calling a C++ method that is in a DLL, from a C# class in a Unity project on Android. I see these error messages:

  • Unable to lookup library path for ‘TestGame’, native render plugin support disabled.
  • DllNotFoundException: Unable to load DLL ‘TestGame’: The specified module could not be found.

In the C# class (in Main.cs), I declared this external C++ method, based on System.Runtime.InteropServices:

[DllImport(“TestGame”)]
static extern void DoSomething(IntPtr handler);

I compiled libTestGame.so for arm64-v8a using Clang and Visual Studio 2017. (I made sure to preserve the case of the filename.)

I copy this file to the same directory that contains the .apk that gets launched. Is this the right directory for my .so? If not, should it be in another directory?

Do the error messages above mean that the .so file is not being found, or could it mean that the contents of the .so are invalid?

Is the .so file supposed to be inside the .apk somehow?

Is the DllImport directive wrong?

This Unity project and C++ DLL work as expected under Windows, with TestGame.dll in the same directory as the .exe.

IL2CPP is involved to allow calling C++ code from C#.

The .apk is also compiled for arm64-v8a, as shown by a log line that says “native-code: ‘arm64-v8a’”.

I appear to be using Unity 2019.3.1f1. The Target API Level is android-24.

Thanks.

I’ve never tried compiling a library .so for Android native.

The two native code interop ways I’ve used Unity/Android are:

  1. build an entire Android Studio native NDK project that emits to an .aar file, drop that into Unity and go.

In this case I can build Mono or IL2CPP and this is the interop bindings:

   [DllImport ("vanilib")]
    private static extern System.IntPtr dispatcher1_entrypoint1(int opcode1, int arg1);

for this C method:

char *dispatcher1_entrypoint1( int opcode1, int arg1);

NOTE: It must be an extern "C" { } function, not C++!

  1. drop the actual C files directly into the project, in which case it will work when compiling IL2CPP and just get “sucked in” as you might expect.

In this case the interop looks like:

    [DllImport( "__Internal")]
    public static extern int Compute( int a, int b);

and it was only a test to access this C method:

int Compute( int a, int b);

Here’s some more of my scribblings:

Pinning a texture for manipulation via native code:

Native code embedding in Android:

1 Like

No, it’s not.

Yes. Put the .so file into Unity project and set the correct settings in the Plugin Inspector, then it will be copied into apk and loaded (well, Unity will attempt to load it).

2 Likes

Thanks for those answers.

Since I’m working from a script, I copied the .so into Demos/Unity/Assets/Plugins/Android before Unity gets called to build the project. The .so ends up in lib/arm64-v8a/ inside the .apk.

Since it’s a C++ library, I had to link it with -lc++_static instead of -lc++_shared so that my .so would not depend on libc++_shared.so, which is apparently not present by default.