so库的路径名称为app/netLib/arm64-v8a/libnetapi.so为什么 以下 这段代码写的却是pwdverify_jni
java
static {
try {
System.loadLibrary("pwdverify_jni");
Log.d(TAG, "Library loaded successfully");
} catch (UnsatisfiedLinkError e) {
Log.e(TAG, "Failed to load library: " + e.getMessage());
}
}
┌──────────────────────────────────────────┐
│ Java 层 (NetApiManager.java) │
│ native int nCheckNetCard(); │ → System.loadLibrary("pwdverify_jni")
└──────────────────┬───────────────────────┘
│ JNI 调用
┌──────────────────▼───────────────────────┐
│ JNI 桥接库 (libpwdverify_jni.so) │ ← CMake 自动编译
│ Java_com_..._NetApiManager_nCheckNetCard│
│ → 内部调用 CheckNetCard() │
└──────────────────┬───────────────────────┘
│ 直接函数调用
┌──────────────────▼───────────────────────┐
│ 原生 C 库 (libnetapi.so) │ ← 预编译,已存在的
│ int CheckNetCard(); │
│ int AuthCardPsw(char*, int); │
│ ... │
└──────────────────────────────────────────┘
关键原因:
1、JNI 函数命名规范 --- Java 通过 native 方法调用 so 库时,要求 so 库中的函数必须是 JNI 规定的命名格式,例如:
java
Java_com_sdt_pwdverifytools_manager_NetApiManager_nCheckNetCard
2、libnetapi.so 是纯 C 导出 --- 它导出的函数名是 CheckNetCard、AuthCardPsw 等纯 C 命名(见 NetApi.txt),Java 虚拟机根本无法识别。
3、桥接层做翻译 --- 所以必须写一个中间层(netapi_jni.c),编译成 libpwdverify_jni.so。这个桥接库:
对外暴露 JNI 规范命名的函数(供 Java 调用)
对内调用 libnetapi.so 的原始 C 函数(通过 CMake 链接
4、自动依赖加载 --- CMake 配置中 libpwdverify_jni.so 链接了 libnetapi.so,所以 Android 动态链接器在加载 pwdverify_jni 时会自动加载 netapi,不需要手动 System.loadLibrary("netapi")。
简单说:libnetapi.so 是"引擎",libpwdverify_jni.so 是"方向盘"------Java 只能通过方向盘来控制引擎