dll库的制作及Java jni的调用

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,这样它就会重新去取最新的值

 

 

你可能感兴趣的:(java)