费了半天劲,终于自己实现了一个简单的java本地方法调用,这里备个份方便以后回顾。
具体步骤如下:
一:编写本地java类,该类中包含本地方法
本地方法需要使用 native进行修饰,并且没有方法体,只有方法声明。
本地方法可以是static或非static的。
具体如下:
<span style="font-size:14px;">public class HelloNative {
public static native void greeting();//这里使用的static,为了避免处理传输参数
}</span>
二:编译该本地方法java类,这里就是HelloNative。
<span style="font-size:14px;"> javac HelloNative.java</span>
然后得到HelloNative.class文件
三:命名你的本地java方法名:
规则使用完整的java方法名,比如HelloNative.greeting;如果有包名则要加上包名,如com.feng.HelloNative.greeting
然后,用_下划线替换所有的.
如果有类名包含非ASCII码字母或数字,如'_'或者是大于'\u007F'的Unicode字符,就用_0XXXX表示,XXXX是该字母的4个十六进制数。
其实你可以直接使用jdk提供的javah 工具(在JDK1.8\bin目录下),就可以实现上面的步骤。
如果你的jdk环境变量没有设置好,你可以直接通过cmd切换到该目录下,这样就可以使用该工具了。
你讲之前的HelloNative.class文件直接拷贝到在JDK1.8\bin目录下(避免设置环境变量麻烦)
--javah HelloNative(注意:这里的HelloNative是.class文件的名字)
就会生成一个该HelloNative类的头文件
具体头文件内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloNative */
#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloNative
* Method: greeting
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloNative_greeting
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
我们需要关注的是:
JNIEXPORT void JNICALL Java_HelloNative_greeting
(JNIEnv *, jclass);
这对于下面用C/C++实现该方法很有帮助。
四:使用C/C++来实现该方法。
在VS2015下创建一个Win32的动态链接库工程。
在该工程下添加实现JNI的头文件:jni.h、jni_md.h和我们自己生成的HelloNative.h头文件
我使用的方法是:直接把这三个头文件直接放到VS2015的Include(库)目录下。
具体为:VS2015\VC\include这个目录。
然后在该项目下创建一个C/C++文件:我这里创建的是HelloNative.cpp
在该文件中包含jni.h和HelloNative.h头文件。
并且注意把方法的原型拷贝过来:
也就是:
JNIEXPORT void JNICALL Java_HelloNative_greeting
(JNIEnv *, jclass);
实现这个方法:
JNIEXPORT void JNICALL Java_HelloNative_greeting
(JNIEnv* env, jclass cl) {
printf("Hello ,Native World!");
}
最后 完整的HelloNative.cpp文件:
<span style="font-size:14px;">#include<jni.h>
#include<HelloNative.h>
JNIEXPORT void JNICALL Java_HelloNative_greeting
(JNIEnv* env, jclass cl) {
printf("Hello ,Native World!");
}</span>
然后编译该文件,就可以得到一个动态链接库.dll文件,我们可以从VS2015中该项目的\HelloNative\x64\Debug
找到该动态链接库文件。
五:将该动态链接库文件添加到环境变量java.library.path定义的目录下,以便于被类加载器搜索到。
可以通过:System.out.println(System.getProperty("java.library.path"));
来查看java.library.path的内容,然后找到一个合适的目录。
我这里选择的目录是:F:\SoftWare\LearnSoftWare\Java\JDK\JDK1.8\jre1.8\bin
六:编写测试类,进行测试:
在使用该native方法之前,要先加载该动态链接库:
我们使用静态代码块,它会在类被加载后,立即执行:
static {
System.loadLibrary("HelloNative");//注意:HelloNative就是我们生成的包含native方法实现的动态库的名字
}
然后我们直接调用本地方法:
public static void main(String[] args) {
HelloNative.greeting();
}
具体的测试代码如下:
public class HelloNativeTest {
public static void main(String[] args) {
//java.library.path
// System.out.println(System.getProperty("java.library.path"));
HelloNative.greeting();
}
//现在加载动态链接库
static {
System.loadLibrary("HelloNative");
}
}
到此完成

注意:一个很头疼的问题,就会我们自己实现的动态链接库必须要和jdk的版本一致
我的是jdk64位,所以生成的动态链接库也要是64位;
否则就会报:Can't load IA 32-bit .dll on a AMD 64-bit platform这个错误。
解决方法:
在编译HelloNative.cpp之前,先进入VS2015的 ->"生成"->"配置管理器"->"活动方法平台"选择64位。
然后再重新点击"生成"->"编译"。