Android项目使用预构建.so库时遭遇UnsatisfiedLinkError问题
问题分析与解决方案
从报错堆栈和你提供的代码信息来看,包名不匹配是触发UnsatisfiedLinkError的核心原因:
- VM在寻找
com.example.library.SwigWbcJNI.WBC_PLAINTEXT_INCORRECT_LENGTH_get()的实现 - 但你生成的JNI函数对应的是
com.onespan.digipass.sdk.wbc.jni.SwigWbcJNI类的方法,两者包名完全不一致,导致VM找不到对应的原生实现
以下是具体解决步骤:
1. 修正Swig生成的Java类包名
在Swig的.i接口文件中,指定正确的包名(要和你代码中引用的com.example.library一致):
%module SwigWbc %package com.example.library; // 设置匹配的包名 %{ #include "你的头文件.h" // 替换为实际的头文件路径 %} // 导入需要生成绑定的头文件 %include "你的头文件.h"
2. 重新生成JNI包装器和Java类
执行Swig命令,重新生成SwigWbc_wrap.cpp和对应的Java类,确保生成的JNI函数前缀为Java_com_example_library_SwigWbcJNI_xxx。
3. 修正CMakeLists.txt配置
当前你注释了SwigWbc_wrap.cpp,说明你可能未将包装器代码编译进库中。如果是自行编译原生库,需要将包装器源码加入编译流程:
cmake_minimum_required(VERSION 3.4.1) add_library( native-lib SHARED # 加入Swig生成的包装器源码 src/main/java/com/example/library/SwigWbc_wrap.cpp ) # 包含头文件目录 include_directories( src/main/jni # 原生头文件所在目录 ) # 链接系统日志库 find_library( log-lib log ) target_link_libraries( native-lib ${log-lib} )
如果使用预编译的.so,要确保预编译库已经包含了Swig包装器的编译结果。
4. 验证函数符号匹配
编译完成后,用nm工具检查.so文件中的函数符号,确认存在目标函数:
# 替换为你的.so文件实际路径 nm -D app/build/intermediates/merged_native_libs/debug/out/lib/arm64-v8a/libnative-lib.so | grep WBC_PLAINTEXT
额外检查点
- 确保
System.loadLibrary("native-lib")在SwigWbcJNI类加载前执行,比如放在类的静态代码块中:
package com.example.library; public class SwigWbcJNI { static { System.loadLibrary("native-lib"); } public final static native int WBC_PLAINTEXT_INCORRECT_LENGTH_get(); }
- 确认APK中包含了对应设备ABI的
.so文件,避免ABI不匹配导致的加载问题。
内容的提问来源于stack exchange,提问作者Oyebisi
相关产品推荐
相关产品推荐

