is 32-bit instead of 64-bit动态库错误分析

本文详细介绍了如何解决Android项目中32位与64位库混用导致的错误问题,提供了两种解决方案:一是通过配置文件过滤64位库文件;二是生成并使用64位库文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载自:http://blog.youkuaiyun.com/chewbee/article/details/51973273

前段时间因项目需要,需要MP3格式的录音,需要引用LAME开源库,在引用so库文件时,提示Java.lang.UnsatisfiedLinkError: dlopen failed: “liblame.so” is 32-bit instead of 64-bit错误,网上分析了出现这种情况的原因,可能是混合使用了32bit和64bit的库文件,如果系统先使用64bit的库文件时,则后续的库文件都是以64bit来加载执行,故会出现此问题。

针对第三方应用,在它安装的时候,安装包管理器会检查该应用是否使用native libraries,如果使用本地库文件的话,则会根据相应的架构abi来选择是32bit还是64bit。

针对系统应用来说,它的库文件存放在/system/lib,所以无法确定该应用是否依赖其他应用在system/lib下的库文件。因此安装包管理器,无法确定系统应用使用哪种架构abi,故在64bit模式下运行。

当你安装应用到系统时,系统会从lib目录下的(armeabi, armeabi-v7a, arm64-v8a, x86, x86_64, mips64, mips)文件夹中查找本地库文件,不同的架构加载不同的文件夹下的库文件。例如64bit的架构从arm64-v8a、x86_64、mips64这些目录中加载。如果你的arm64-v8a文件夹下刚好有这个需要使用到的库文件,则不会从其他文件夹如armeabi加载该库文件。此时就会出现32bit库文件和64bit库文件混合使用的情况,但是32bit的库文件不能和64bit的库文件不能混合使用。因此,有一种解决办法是过滤掉64bit的库文件,全部使用32bit的库文件。在Android studio配置文件build.gradle(Module APP)中配置如下:

android {
    ....
    defaultConfig {
        ....
        ndk {
            abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
        }
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

还有一种解决办法是生成64bit库文件,具体的做法如下,在jni目录下创建一个Application.mk文件,定义需要生成的abi架构库文件。64bit库文件可以选择arm64-v8a abi架构。

[plain] view plain copy 
在CODE上查看代码片派生到我的代码片

    APP_MODULES := JNITest  
    APP_ABI := arm64-v8a  
 
 
  • 1
  • 2
  • 1
  • 2

其中APP_MODULES 是需要生成的模块名字,在Android.mk文件的LOCAL_MODULE中定义。

APP_ABI,默认情况下,NDK的编译系统根据 “armeabi” ABI生成机器代码。可以使用APP_ABI 来选择一个不同的ABI。这里选择arm64-v8a来表示需要生成64bit的库文件。

注意,如果需要编译64bit库文件,需要使用64bit的ndk版本。64bit ndk下载。 
这里写图片描述

编译出64bit 的库文件之后,用该库文件替换32bit 库文件,就可以解决该问题。

参考链接:

http://stackoverflow.com/questions/27712921/how-to-use-32bit-native-libraries-on-64-bit-android-l-platform

http://stackoverflow.com/questions/30782848/how-to-use-32-bit-native-libaries-on-64-bit-android-device

### 错误原因 当应用程序尝试在一个64位架构的设备上加载32位本地库文件(`.so` 文件),会触发 `java.lang.UnsatisfiedLinkError: dlopen failed * is 32-bit instead of 64-bit` 的异常。这是因为 Android 设备在启动应用时,默认情况下只会加载与当前 CPU 架构相匹配版本的 `.so` 库文件[^1]。 ### 解决方案概述 为了确保应用程序能够在不同架构的设备上正常工作,开发者应提供适用于目标平台的所有 ABI 版本的原生库。具体来说,在构建过程中应当包含针对 ARMv7 (32-bit), ARM64 (64-bit),以及可能存在的其他架构的支持[^2]。 ### 实施步骤 #### 修改 Gradle 配置 通过调整项目的 `build.gradle` 文件来指定所需的ABI过滤器: ```groovy android { ... defaultConfig { ... externalNativeBuild { cmake { cppFlags "" } } ndk { abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' } } } ``` 上述配置指定了四个常见的ABI:两个用于ARM处理器(分别对应32位和64位),另外两个则是面向Intel架构的CPU。这可以有效防止因缺少适当架构下的共享对象而导致的应用崩溃问题[^4]。 #### 清理旧版构建产物 有时即使更新了Gradle设置之后仍然遇到相同的问题,可能是由于缓存中的陈旧二进制文件干扰所致。因此建议执行如下命令清理项目: ```bash ./gradlew clean ``` 接着重新编译整个工程以确保所有更改生效。 #### 检查第三方依赖项 如果使用到了外部库,则需确认这些库也提供了相应的多ABI支持。可以通过查阅文档或联系维护者获取更多信息。必要时考虑寻找替代品或是请求作者增加对更多ABI的支持[^3]。 ### 注意事项 - 不要简单地移除特定ABI的支持作为临时解决方案,因为这样做可能会缩小潜在用户的范围。 - 对于不需要访问底层硬件特性的纯Java/Kotlin应用而言,通常不会受到此问题的影响;但如果集成了任何形式的JNI接口或者直接调用了C/C++代码编写的功能模块,则务必重视这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值