Java代码
package cn.com.comit.jni; public class HelloJni { public native void displayHelloJni(); static{ System.loadLibrary("hello"); } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub new HelloJni().displayHelloJni(); } }
编译class后
javah cn.com.comit.jni.HelloJni 生成对应的c的头文件
cn_com_comit_jni_HelloJni.h
编写C程序的实现
#include <jni.h> #include <stdio.h> #include "cn_com_comit_jni_HelloJni.h" JNIEXPORT void JNICALL Java_cn_com_comit_jni_HelloJni_displayHelloJni (JNIEnv *, jobject) { printf("Hello Jni .....\n"); return ; }
cl -I %java_home%\include -I %java_home%\include\win32 -LD Hello.cpp -Fehello.dll
生成动态库,jni.h该头文件在java_home中,所以要包含过来进行编译
cl类似于linux中的gcc
运行Java代码测试
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.library.path
hello.dll必须是在JVM属性java.library.path所指向的路径中
1、-Djava.library.path=./c 或动态的形式
2、System.setProperty("java.library.path", System.getProperty("java.library.path") + ";./c");
两种方式的区别:
如果想在程序中加载一些库文件,使用第一种方式指定java.library.path属性时可以正常载入,而使用第二中方式就不行。java.library.path只有在JVM启动的时候读取一次,因此在java代码中更改java.library.path是不起任何作用的。我们还可以在代码中使用System.load("/jni/library/absolute/path")来加载绝对地址指定的本地库。
如果用代码的形式设置必须如下:
System.setProperty("java.library.path", System.getProperty("java.library.path") + ";./c");
Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
fieldSysPath.setAccessible(true);
fieldSysPath.set(null, null);//设置为null,这样它就会重新去取最新的值