JNI简单教程
功能描述
使用java的jni去调用C语言写的函数,以下以树莓派环境为例,实现LED灯点亮
一)本地编写native方法
package com.homkey.jni;
public class NativeLed {
static {System.loadLibrary("NativeLed");}
public static native int led();
public static void main(String[] args) {}
}
好像一定要写main函数,不然会报错
二)javac编译获取到class文件
javac NativeLed.java
三)javah编译获取到头文件(.h)
javah -classpath . -jni com.homkey.jni.NativeLed
一定要把路径调整到src/main/java目录下执行,并且相对于包路径
得到com_homkey_jni_NativeLed.h头文件如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_homkey_jni_NativeLed */
#ifndef _Included_com_homkey_jni_NativeLed
#define _Included_com_homkey_jni_NativeLed
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_homkey_jni_NativeLed
* Method: led
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_homkey_jni_NativeLed_led
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
四)编写C语言函数
按照得到的头文件格式编写对应的C函数内容
#include "jni.h"
#include <stdio.h>
#include "com_homkey_jni_NativeLed.h"
#include <bcm2835.h>
#define RUN 30
JNIEXPORT jint JNICALL Java_com_homkey_jni_NativeLed_led
(JNIEnv *env, jclass c1){
printf("start\n");
if (!bcm2835_init()){
printf("no init\n");
return -1;
}
printf("init\n");
bcm2835_gpio_fsel(RUN,BCM2835_GPIO_FSEL_OUTP);
int i = 5;
while (i > 0)
{
printf("while start\n");
bcm2835_gpio_write(RUN,HIGH);
//printf("high\n");
bcm2835_delay(1000);
bcm2835_gpio_write(RUN,LOW);
//printf("low\n");
bcm2835_delay(1000);
printf("while end\n");
i--;
}
bcm2835_close();
printf("end\n");
return 1;
}
五)GCC编辑得到so文件
把com_homkey_jni_NativeLed.h和NativeLed.c文件放到树莓派的同一个目录上执行gcc,编译得到so文件
gcc -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -shared -o libDiledJni.so DiledJni.c -l bcm2835
so文件名要加lib前缀,linux环境下System.loadLibrary(“NativeLed”)会默认加上lib前缀
-l bcm2835是因为#include <bcm2835.h>所以要加
六)把so文件放到JDK对应的目录下
我的是在arm目录
mv libNativeLed.so $JAVA_HOME/jre/lib/arm
七)native调用示例
完成上述步骤后即可直接调用步骤(一)的NativeLed类的native方法
package com.homkey;
import com.homkey.jni.NativeLed;
public class ApplicationMain {
public static void main(String[] args) {
System.out.println("main start");
NativeLed.led();
System.out.println("main end");
}
}
输出: