linux环境jni demo

step 1 准备接口文件

先弄个java文件 Hi.java:

(我是把要测试的代码顺便也写好了,main不是必须的)

public class Hi {
    static {
            System.loadLibrary("Hi");
    }
    //声明的本地方法
    public  static native void Fun1(String strName);
    public  static native String Fun2(String strName);
    public static void main(String[] args) {
        Fun1("boy");
        System.out.println(Fun2("girl") + ", print in JAVA.");
    }
}

step 2 编译class

javac Hi.java

生成 Hi.class

step 3 生成 Hi.h 头文件

javah -classpath . Hi

生成 Hi.h 。内容如下,不需要修改:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Hi */

#ifndef _Included_Hi
#define _Included_Hi
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Hi
 * Method:    Fun1
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_Hi_Fun1
  (JNIEnv *, jclass, jstring);

/*
 * Class:     Hi
 * Method:    Fun2
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_Hi_Fun2
  (JNIEnv *, jclass, jstring);

#ifdef __cplusplus
}
#endif
#endif

step 4 实现 Hi.c 对应功能

关于java的变量和c变量的对接使用规则,自行查百度。

#include "Hi.h"
#include <stdio.h>

//与Hi.h中函数声明相同

JNIEXPORT void JNICALL Java_Hi_Fun1  (JNIEnv * env, jclass arg, jstring instring)
{
    //从instring字符串取得指向字符串UTF编码的指针
    const jbyte *str = (const jbyte *)env->GetStringUTFChars( instring, JNI_FALSE );
    printf("[Fun1]Hello, olami, I'm %s, print in C.\n",str);
    //通知虚拟机本地代码不再需要通过str访问Java字符串。
    env->ReleaseStringUTFChars( instring, (const char *)str );
    return;
}

JNIEXPORT jstring JNICALL Java_Hi_Fun2  (JNIEnv * env, jclass arg, jstring instring)
{
    char tmpstr[100];
    const jbyte *str = (const jbyte *)env->GetStringUTFChars( instring, JNI_FALSE );
    sprintf(tmpstr, "[Fun2]Hello, olami, I'm %s",str);
    env->ReleaseStringUTFChars( instring, (const char *)str );
    return env->NewStringUTF(tmpstr);
}

step 5 编译 Hi.c

依赖jdk中两个文件: jni.h 和 jni_md.h ;因为这两个文件在我试验机器上的两个目录,所以下述命令里需要有两个 -I 参数来指定 include 路径。

找不到这两个文件?? 可能你的机器上装的只有JRE,装一下JDK就能找到了。

g++ -I /usr/lib/jvm/java-8-openjdk-armhf/include/linux/ -I /usr/lib/jvm/java-8-openjdk-armhf/include/ -fPIC -shared -o libHi.so Hi.c

上述命令会生成 libHi.so

step 6 将libHi.so移到java.library.path中

windows环境中,会默认先找当前路径,所以不需要这一步。

linux环境下,使用libHi.so,有以下三种方式:

方式一

用java代码打印出 System.getProperty(“java.library.path”) 路径,然后把 libHi.so 拷到任意一个路径中。

方式二

添加环境变量 LD_LIBRARY_PATH ,将当前目录加到变量中:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

方式三

直接运行时带参数,如:

java -Djava.library.path=.  -cp . Hi

step 7 运行体验

使用上一步中的方式三,直接运行即可看到效果。

附全程主要操作日志:

pi@bpi-iot-ros-ai:~/jni/demo$ ll
total 16
drwxrwxr-x 2 pi pi 4096 May 23 17:29 ./
drwxrwxr-x 3 pi pi 4096 May 23 17:06 ../
-rw-rw-r-- 1 pi pi  871 May 23 17:28 Hi.c
-rw-rw-r-- 1 pi pi  348 May 23 17:28 Hi.java
pi@bpi-iot-ros-ai:~/jni/demo$ javac Hi.java 
pi@bpi-iot-ros-ai:~/jni/demo$ 
pi@bpi-iot-ros-ai:~/jni/demo$ ll
total 20
drwxrwxr-x 2 pi pi 4096 May 23 17:30 ./
drwxrwxr-x 3 pi pi 4096 May 23 17:06 ../
-rw-rw-r-- 1 pi pi  871 May 23 17:28 Hi.c
-rw-rw-r-- 1 pi pi  785 May 23 17:30 Hi.class
-rw-rw-r-- 1 pi pi  348 May 23 17:28 Hi.java
pi@bpi-iot-ros-ai:~/jni/demo$ javah -classpath . Hi
pi@bpi-iot-ros-ai:~/jni/demo$ ll
total 24
drwxrwxr-x 2 pi pi 4096 May 23 17:30 ./
drwxrwxr-x 3 pi pi 4096 May 23 17:06 ../
-rw-rw-r-- 1 pi pi  871 May 23 17:28 Hi.c
-rw-rw-r-- 1 pi pi  785 May 23 17:30 Hi.class
-rw-rw-r-- 1 pi pi  528 May 23 17:30 Hi.h
-rw-rw-r-- 1 pi pi  348 May 23 17:28 Hi.java
pi@bpi-iot-ros-ai:~/jni/demo$ g++ -I /usr/lib/jvm/java-8-openjdk-armhf/include/linux/ -I /usr/lib/jvm/java-8-openjdk-armhf/include/ -fPIC -shared -o libHi.so Hi.c
pi@bpi-iot-ros-ai:~/jni/demo$ ll
total 36
drwxrwxr-x 2 pi pi 4096 May 23 17:30 ./
drwxrwxr-x 3 pi pi 4096 May 23 17:06 ../
-rw-rw-r-- 1 pi pi  871 May 23 17:28 Hi.c
-rw-rw-r-- 1 pi pi  785 May 23 17:30 Hi.class
-rw-rw-r-- 1 pi pi  528 May 23 17:30 Hi.h
-rw-rw-r-- 1 pi pi  348 May 23 17:28 Hi.java
-rwxrwxr-x 1 pi pi 8312 May 23 17:30 libHi.so*
pi@bpi-iot-ros-ai:~/jni/demo$ java -Djava.library.path=.  -cp . Hi
[Fun1]Hello, olami, I'm boy, print in C.
[Fun2]Hello, olami, I'm girl, print in JAVA.
pi@bpi-iot-ros-ai:~/jni/demo$ 
pi@bpi-iot-ros-ai:~/jni/demo$

C/C++调JAVA,可以试试:https://blog.csdn.net/xdw1985829/article/details/6907745

发表评论

电子邮件地址不会被公开。 必填项已用*标注

😉😐😡😈🙂😯🙁🙄😛😳😮:mrgreen:😆💡😀👿😥😎😕