初探JNI-最简单的JNI封装

36 阅读2分钟

Native方法的定义

Native方法是Java中一种特殊的方法,它:

  1. 声明方式:使用 native 关键字修饰,没有方法体

    public class Calculator {
     // 加载本地库
     static {
         System.loadLibrary("calculator");
     }
     
     // 声明native方法
     public native int add(int a, int b);
     public native int subtract(int a, int b);
     public native int multiply(int a, int b);
     public native double divide(int a, int b);
     
     // Java中定义的方法
     public int power(int base, int exponent) {
         return (int) Math.pow(base, exponent);
     }
     
     public static void main(String[] args) {
         Calculator calc = new Calculator();
         
         System.out.println("Java调用C++类接口示例:");
         System.out.println("10 + 5 = " + calc.add(10, 5));
         System.out.println("10 - 5 = " + calc.subtract(10, 5));
         System.out.println("10 * 5 = " + calc.multiply(10, 5));
         System.out.println("10 / 5 = " + calc.divide(10, 5));
         System.out.println("2 ^ 3 = " + calc.power(2, 3));
     }
    }
    
  2. 实现方式:在Java中只声明,实际实现在本地代码(如C/C++)中完成

  3. 调用机制:通过JNI(Java Native Interface)与本地代码进行交互

工作原理

  • Java代码中声明native方法
  • 实际功能在C/C++等本地语言中实现
  • 通过JNI桥接Java和本地代码
  • 运行时动态加载包含native实现的共享库

使用场景

根据文档描述,native方法主要用于:

  • 访问底层系统资源
  • 调用现有的C/C++库
  • 执行对性能要求较高的计算

命名规范

JNI对native方法有严格的命名规则:

  • Java_ 为前缀
  • 后跟完整的类名和方法名
  • 例如:Java_HelloJNI_sayHello

这种机制允许Java程序利用本地代码的能力,同时保持平台无关性。

这段代码是Java中用于加载本地库的关键代码,让我详细解释一下:

代码解析

static

  • 作用:静态初始化块,在类第一次被加载时执行
  • 时机:在任何实例创建之前,且只执行一次
  • 用途:用于初始化类级别的资源

System.loadLibrary("calculator")

  • 功能:加载名为 "calculator" 的本地库(Native Library)
  • 参数:库名称(不包含前缀 lib 和后缀如 .so.dll 等)
  • 工作原理
    • JVM会自动添加平台相关的前缀和后缀
    • Linux/Unix: 查找 libcalculator.so
    • Windows: 查找 calculator.dll
    • macOS: 查找 libcalculator.dylib

加载过程

  1. 库定位:JVM在以下位置查找库文件:

    • -Djava.library.path 指定的路径
    • 系统默认库路径
    • 当前工作目录
  2. 库加载:将本地库加载到JVM进程中

  3. 符号链接:建立Java native方法与本地函数之间的链接

示例说明

在您提供的例子中:

static {
    System.loadLibrary("calculator");
}