Android JNI桥接

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 只能通过方向盘来控制引擎