环境准备:
1、安装JDK,并配置好环境变量(使用Java命令)
2、安装minGW,并配置好环境变量(使用gcc和g++命令)
3、Java开发IDE,如IDEA
步骤:
一、创建一个Java工程,写一个java文件 ,注意packge命名
package com.xp;
public class Hello {
public native void sayHello();
static {
System.loadLibrary("Hello");//加载生成的dll文件
}
public static void main(String[] args) {
new Hello().sayHello();
}
}
使用javac 命令生成 class文件
C:\Users\Administrator\IdeaProjects\JniDemo\src>javac com/xp/Hello.java
二、根目录(即src目录)执行命令:javah -d ./jniDir/ -classpath ./ -jni -v com.xp.Hello,生成C++的头文件,命令行中的 com.xp.Hello 表示Java文件的全路径(含package)
C:\Users\Administrator\IdeaProjects\JniDemo\src>javah -d ./jniDir/ -classpath ./ -jni -v com.xp.Hello
[Creating file RegularFileObject[.\jniDir\com_xp_Hello.h]]
生成的.h文件 内容如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_xp_Hello */
#ifndef _Included_com_xp_Hello
#define _Included_com_xp_Hello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_xp_Hello
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_xp_Hello_sayHello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
写一个.h的实现类 .cpp文件,命名为 com_xp_Hello.cpp,文件代码如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include "com_xp_Hello.h"
/*
* Class: com_xp_Hello
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_xp_Hello_sayHello (JNIEnv *, jobject){
printf("Hello JNI.\n");
}
【注意】: #include "com_xp_Hello.h"
三、使用g++命令编译生成dll文件,即第一步中的java文件加载的dll文件
C:\Users\Administrator\IdeaProjects\JniDemo\src>g++ -shared -fPIC -I "C:\Program Files\Java\jdk1.8.0_131\include" -I "C:\Program Files\Java\jdk1.8.0_131\include\win32" jniDir/com_xp_Hello.cpp -o Hello.dll
命令行解析:
-o 表示输出的结果是一个dll文件,文件名是 Hello
-I 引入,这里需要用到JDK的include目录和win32目录中的某几个.h文件
最终生成的Hello.dll文件在src目录,即敲命令的目录
四、使用 java命令运行class文件,运行参数中加载dll文件
C:\Users\Administrator\IdeaProjects\JniDemo\src>java -Djava.library.path=./ com.xp.Hello
Hello JNI.
命令行解析:
-Djava.library.path=./ 加载的library所在的目录,这里的./表示当前目录
【总结】
1、Java调native接口其实就是把C++的的代码生成dll代码库,然后在执行class文件的时候加载dll代码库的,因此,第一步的Java代码需要一步到位,包括dll文件的命名
2、注意理解命令行的参数,以及文件目录
3、如果是Linux环境,第三步的命令的 -o 参数的值为 libHello.so(注意前面有个lib)
so:shared object,共享库,Linux环境下使用,对应Windows下的dll
dll:dynamic link library,动态链接库,Windows环境下使用,对应Linux下的so
所有文件的目录层级关系如下:
src
|Hello.dll
|com
|xp
Hello.class
Hello.java
|jniDir
com_xp_Hello.cpp
com_xp_Hello.h
感谢这边文章的博主提供的参考: