【问题标题】:Android APK doesn't have the .so in the right directoryAndroid APK 在正确的目录中没有 .so
【发布时间】:2011-02-25 07:10:00
【问题描述】:

我正在使用 Eclipse 3.6 开发一个相对简单的 Android NDK 项目。我毫无问题地构建了我的共享库,并且 ndk-build 将它放在 libs/armae​​bi 中(注意:我没有在我的 Android.mk 或 Application.mk 文件中指定该目录)。当我尝试在模拟器上运行项目时,我得到了 UnsatisfiedLinkError。

然后,我检查了所有内容,确保调用了 System.loadlibrary、验证了我的标头等,一切看起来都正常。最后,我注意到 logcat 说它正在寻找 ../lib not ../libs/armeabi 中的文件。然后我手动创建了一个 lib 目录并将我的 .so 放在那里,但仍然遇到同样的错误。当我解压 APK 时,我可以看到 Eclipse 仍然将它放在 ../lib/armae​​bi 目录中。我尝试删除/添加项目、寻找设置等,但没有成功。

我的问题是:到底发生了什么?这真的很愚蠢吗?一个我似乎找不到的地方?还是它以某种方式依赖于 API 版本? Eclipse 如何决定将 .so 放在哪个目录,因为它显然忽略了我在项目中的结构!

在此先感谢大家。

-帕维尔

【问题讨论】:

    标签: android eclipse shared-libraries android-ndk


    【解决方案1】:

    Android 包管理器将库安装到 lib/ 而不是 lib/armeabi,所以那里没有问题。 armeabi 位于 APK 中,因为您可以针对 armeabi 或 armeabi-v7a 进行编译,并且包管理器会为设备安装最合适的库。

    UnsatisfiedLinkError 很可能是由于您的 JNI 函数签名中的错误。您可以通过javah 程序运行编译的类文件来检查签名应该是什么。任何差异都是错误的原因。

    【讨论】:

    • 非常感谢@richq。我检查了.h,它与.cpp 匹配。还有其他想法吗?
    • 如果你使用的是 C++,你没有错位符号对吧?它们应该是extern "C",并确保 C++ 函数名称对于定义它们的 Java 类和方法名称是正确的(除非您使用的是 RegisterNatives)。
    【解决方案2】:

    UnsatisfiedLinkError ,可能是由于平台兼容性不匹配。如果您已经为 2.2 版本编译了库并尝试在 2.1 设备上运行,则可能会出现此错误。请检查一下。

    【讨论】:

      【解决方案3】:

      您的共享库是否链接到另一个库? Android 不会为你加载依赖库;你必须在Java 之前 加载依赖库。这是我的应用程序中的一个示例,它使用 NativeActivity,但会覆盖它以首先加载依赖的库:

      package com.audia.dev.dummyandroid;
      import android.app.NativeActivity;
      import android.os.Bundle;
      
      public class DummyAndroid extends NativeActivity {
          @Override
          public void onCreate(Bundle savedInstanceState)
          {
              //load libraries we depend on first
              System.loadLibrary("QtCore");
              System.loadLibrary("QtNetwork");
              System.loadLibrary("QtGui");
              System.loadLibrary("qtandroid");
              super.onCreate(savedInstanceState);
          }
      }
      

      从日志中给出确切的错误可能会有所帮助。

      【讨论】:

      • 这并不完全正确。 ELF 支持将共享库与其他共享库链接,并且它们很好地被 Android 在运行时引入。在 Qt 的情况下,问题可能是库没有相互链接,或者 .so 没有链接到它使用的所有库。如果您将 .so 链接到 QtCore、QtNetwork、QtGui 和 qtandroid,那么所有这些都应该使用 .so 加载。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-05
      • 2014-07-16
      • 1970-01-01
      • 2013-05-17
      • 2021-07-01
      • 1970-01-01
      • 2016-08-15
      相关资源
      最近更新 更多