为什么Unity在与OpenCV链接时无法加载android本机库?

时间:2022-09-01 09:19:44

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.

标题说明了一切。我正在使用NDK构建一个本机库,用于Unity(游戏引擎,而不是Ubuntu shell)。我已经有很多代码,它适用于运行Android 4.4.4的Xperia Z Ultra。然而,最近我将该应用程序发送给其他人在他们的手机上进行测试,并且它没有在他们的手机上工作。他们使用的是Android 4.0和4.1,所以我尝试在我自己的Android 4.0.4设备(旧的Xperia Mini Pro)上运行该应用程序并遇到了同样的问题。经过大幅缩小后,我发现问题的根源是在构建中包含OpenCV,即使它根本没有被引用。

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

这是我现在的代码。首先,您看到的最简单的CPP文件:

//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:

请注意它甚至不包含任何来自OpenCV的内容。 makefile(或者在NDK的上下文中调用的任何东西,我主要是Windows / Visual Studio人员)是:

#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:

构建这个项目给了我一个“libTest.so”文件。我将它放入我的Unity项目,在Assets / Plugins / Android /(我也尝试将它放在Plugins / Android / libs / armeabi-v7a /中,没有运气)。我还有一个内部的脚本调用库:

//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:

当我在Z Ultra上运行它时,它运行得很好。当我在Mini Pro上运行它时,它失败并出现“DllNotFoundException:Test”异常。我已经检查了logcat的错误,这就是它所说的:

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.

它没有说什么,只是失败了。它在4.4.4上运行的事实让我觉得它可能与构建配置或类似的东西有关,但我无法弄清楚它是什么。有任何想法吗?谢谢。

2 个解决方案

#1


1  

I found out, after much trial and error, that the reason for the error is that Android somehow manages to mess the library dependencies up. The work-around is to manually load the libraries in the specific order of their dependencies, using LoadLibrary. This can be done in Unity using AndroidJavaClass to avoid having to write an entire jar library just for loading the native ones.

经过多次试验和错误后,我发现错误的原因是Android以某种方式设法弄乱了库依赖项。解决方法是使用LoadLibrary以其依赖项的特定顺序手动加载库。这可以使用AndroidJavaClass在Unity中完成,以避免编写整个jar库只是为了加载本机库。

#2


0  

You have to build a .so that correspond to the architecture of the device your are using. You should look at this link : https://developer.nvidia.com/AndroidWorks It provides useful tools to develop on Android with Visual Studio You can easily configure an Android Dynamic Library (.so) that correspond to the architecture you need :)

您必须构建一个与您正在使用的设备的体系结构相对应的.so。您应该查看以下链接:https://developer.nvidia.com/AndroidWorks它提供了使用Visual Studio在Android上进行开发的有用工具您可以轻松配置与您需要的体系结构相对应的Android动态库(.so):)

#1


1  

I found out, after much trial and error, that the reason for the error is that Android somehow manages to mess the library dependencies up. The work-around is to manually load the libraries in the specific order of their dependencies, using LoadLibrary. This can be done in Unity using AndroidJavaClass to avoid having to write an entire jar library just for loading the native ones.

经过多次试验和错误后,我发现错误的原因是Android以某种方式设法弄乱了库依赖项。解决方法是使用LoadLibrary以其依赖项的特定顺序手动加载库。这可以使用AndroidJavaClass在Unity中完成,以避免编写整个jar库只是为了加载本机库。

#2


0  

You have to build a .so that correspond to the architecture of the device your are using. You should look at this link : https://developer.nvidia.com/AndroidWorks It provides useful tools to develop on Android with Visual Studio You can easily configure an Android Dynamic Library (.so) that correspond to the architecture you need :)

您必须构建一个与您正在使用的设备的体系结构相对应的.so。您应该查看以下链接:https://developer.nvidia.com/AndroidWorks它提供了使用Visual Studio在Android上进行开发的有用工具您可以轻松配置与您需要的体系结构相对应的Android动态库(.so):)