“dlopen的失败:是32位而不是64位的”在测试中仅

问题描述:

我具有使用基于C的核心模块的一组或摇篮模块++代码:“dlopen的失败:是32位而不是64位的”在测试中仅

  • 核心(C++使用JNI胶,aarlibxyz-jni.so
  • 测试(Android的仪器测试)
  • 应用(经常Android应用)

Core模块包括本地32位libxyz-jni.so汇编为armeabi-v7ax86,并编译为aar。它没有arm64库。

App模块依赖于Core并正在arm64硬件设备上没有任何问题(能够加载libxyz-jni.so

Tests取决于Core和加载失败libxyz-jni.so(与System.loadLibrary(..))与以下错误:

java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/package.tests.test-2/lib/arm/libxyz-jni.so" is 32-bit instead of 64-bit.

我已经检查过测试apk不包含除了armeabi-v7ax86之外的任何曲拱。测试可以在Android模拟器中运行,但不能在具有Android Nougat的64位硬件设备上运行。该应用程序可以在arm64设备上运行。

这就是加载库方面的测试和应用程序的区别?

+0

x86和armeabi都是32位的。你需要一个为arm64编译的 - 你如何实现这一点,我不太确定。您不能在共享库和使用它们的应用程序之间混合使用“位”(唯一适用于从应用程序调用操作系统的地方,这是通过特殊的模式切换接口完成的,即使对于“相同”因为内核模式和用户模式的行为不同) –

+0

我刚刚尝试过Nougat arm64模拟器,我可以运行应用程序,但无法运行测试,尽管本机库对于测试和应用程序来说绝对是相同的。你怎么能解释32位'libxyz-jni.so'可以加载在arm64'设备/模拟器的应用程序,但不能在测试?如何使它在测试中也能工作? – 4ntoine

+0

它不能,你正在加载应用程序的x86版本和它的库(或类似的东西)。您需要匹配可执行文件和库对。我无法告诉你到底需要完成哪些步骤才能实现这一目标,但是我正在为x86和ARM开发代码,并且每次都会遇到混淆了库的问题 - 它带来了这个问题,你必须通过获得正确的位和处理器架构来解决它。 –

你应该检查你的应用程序在运行时使用的库。你可以用这些命令做到这一点:

# get your running pid 
adb shell ps | grep <your package name> | tr -s ' ' | cut -d ' ' -f 2 
32333 
adb shell lsof | grep 32333 | grep so 
.xxx 32333 u0_a222 mem  REG    259,30 133152  2629 /system/lib64/libcompiler_rt.so 
.xxx 32333 u0_a222 mem  REG    259,30  30824  2759 /system/lib64/libmemalloc.so 

正如你在这种情况下看到Android已经加载lib64的库。如果您希望它默认加载32位库,则需要在您的APK中安装lib/armeabi-v7a/lib.so。

如果你在APK的其他地方有你的库,并且你提取并动态加载,Android不会知道它们是32位。