java jni调用c函数实例分享(java调用c函数)


在Java中通过JNI(Java Native Interface)调用C函数是一个常见的需求,用于扩展Java的功能,特别是在需要高性能计算或访问系统级API时。下面是一个简单的例子,展示如何在Java中通过JNI调用一个C函数。

### 步骤 1: 创建C函数

首先,你需要一个C函数。假设我们有一个简单的C函数,用于计算两个整数的和。


// 文件名: Add.c
#include <jni.h>
#include "Add.h"

JNIEXPORT jint JNICALL Java_Add_add(JNIEnv *env, jobject obj, jint a, jint b) {
    return a + b;
}

这里,我们使用了JNI的头文件`jni.h`,并且假设存在一个头文件`Add.h`,该头文件由`javah`工具自动生成(但在较新版本的JDK中,`javah`已被废弃,你可以使用`javac`和`javap`命令手动生成头文件)。

### 步骤 2: 创建Java类并声明本地方法

然后,在Java中声明一个类,并在其中声明一个native方法。


// 文件名: Add.java
public class Add {
    // 声明native方法
    public native int add(int a, int b);

    // 加载包含native方法实现的库
    static {
        System.loadLibrary("add");
    }

    public static void main(String[] args) {
        Add adder = new Add();
        System.out.println("The sum is: " + adder.add(5, 3));
    }
}

### 步骤 3: 生成头文件

编译Java类(使用`javac`),然后使用`javah`(或`javac -h`)生成C的头文件。


javac Add.java
javah -jni Add

这将生成一个名为`Add.h`的头文件,其中包含`Java_Add_add`函数的签名。

### 步骤 4: 编译C代码为动态链接库

使用适当的编译器(如gcc)将C代码编译为动态链接库(在Windows上是DLL,在Linux和macOS上是.so文件)。


gcc -shared -fpic -o libadd.so -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux Add.c

注意:`${JAVA_HOME}`需要替换为你的Java安装目录的路径,并且`-I${JAVA_HOME}/include/linux`可能需要根据你的操作系统进行调整(例如,在macOS上可能是`-I${JAVA_HOME}/include/darwin`)。

### 步骤 5: 运行Java程序

确保动态链接库在你的系统库路径中,或者通过设置`java.library.path`系统属性来指定它。


java -Djava.library.path=. Add

这样,当Java程序运行时,它会加载`libadd.so`(或你的系统对应的库文件),并调用其中的`Java_Add_add`函数。

请注意,这个例子是基于Linux系统的,如果你在Windows上工作,你可能需要修改编译命令和库文件的扩展名(使用`.dll`而不是`.so`),并可能需要配置环境变量来确保Java可以找到DLL文件。