您的位置:首页 > 编程语言 > Java开发

java jni编程之hello world

2017-11-06 23:34 176 查看
JAVA 本机接口(JAVA native interface) JNI 是一个编程接口;

什么场合下应该使用JNI

当你开始着手准备一个使用JNI的项目时,请确认是否还有替代方案。应用程序使用JNI会带来一些副作用。下面给出几个方案,可以避免使用JNI的时候,达到与本地代码进行交互的效果:
1、JAVA程序和本地程序使用TCP/IP或者IPC进行交互。
2、当用JAVA程序连接本地数据库时,使用JDBC提供的API。
3、JAVA程序可以使用分布式对象技术,如JAVA
IDL API。
这些方案的共同点是,JAVA和C处于不同的线程,或者不同的机器上。这样,当本地程序崩溃时,不会影响到JAVA程序。
下面这些场合中,同一进程内JNI的使用无法避免:
1、程序当中用到了JAVA API不提供的特殊系统环境才会有的特征。而跨进程操作又不现实。
2、你可能想访问一些己有的本地库,但又不想付出跨进程调用时的代价,如效率,内存,数据传递方面。
3、JAVA程序当中的一部分代码对效率要求非常高,如算法计算,图形渲染等。
总之,只有当你必须在同一进程中调用本地代码时,再使用JNI。

缺点

1、程序不再跨平台。要想跨平台,必须在不同的系统环境下重新编译本地语言部分。
2、程序不再是绝对安全的,本地代码的不当使用可能导致整个程序崩溃。一个通用规则是,你应该让本地方法集中在少数几个当中。这样就降低了JAVA和C之间的耦合性

编程,来举个栗子:helloworld

一、

编写Java代码:

public class Helloworld {
// 使用C 或C++ 实现输出
public native void sayHello();

public static void main(String[] args) {
System.loadLibrary("mydll");
new Helloworld().sayHello();
}
}


使用javah.exe (命令在JDK bin目录下)生成头文件 ;

javah [-classpath  class目录] 全类名  [-d 输出目录]//生成头文件
也可cd 到class目录下 javah 全类名  缺省生成,在class 目录下生成


二、使用vs新建dll 动态链接库项目









然后把生成头文件拷贝到VS 源码目录,一定要在文件夹上拷贝,不能直接粘贴到VS 上;

然后在vs源码上右键添加文件;





然后再拷贝jdk 下include目录下的jni.h 以及win32目录下的jni_md.h 文件到 VS项目源码目录下,按照上一步添加到源码





把jni.h中的依赖修改成双引号<jni_md.h> 改成 “jni_md.h”,以及hello头文件的jni也要修改

然后变下cpp文件,编写代码:



三、编译打包 针对运行的虚拟机 选择32位还是64位,我是64系统的所以选择64,默认是32位的,故编64位的记得设置







在解决方案的目录下 会生成dell目录 下生成dll(是解决方案目录,不项目目录),如果是设置release会生成 x64目录下生成dll

四、java调用dll 中的方法;

//
public class Helloworld {
    // 使用C 或C++ 实现输出
    public native void sayHello();

    public static void main(String[] args) {
        //
        /**
         * java调用dll文件,那就要让java知道有dll的存在,网上很多说直接把vs生成dll目录加入path目录,
         * 经我测试这个方法是不可取的,因为java的运行path并不和系统的path值一致,可能因系统而异,
         * 检验方法,在runtime对象找path,确认dll是否在其中path目录
         *
         * Properties properties = System.getProperties();
         * String path = properties.getProperty("PATH");
         *  Map<String, String> evn = System.getenv();
         *  
         *  直接拷贝dll到系统的C:\Windows\System32 目录下是没问的,这个是系统默认运行目录,找不到目录的,使用上述代码运行查找原因
         *  
         *  
         *  
         */
        System.loadLibrary("mydll");
        //  System.load("路径/mydll.dll");
        //使用文件路径加载,不过dll在不在path目录下,可直接加载,建议使用这个方法,修改之后不用拷贝dll,直接运行
        new Helloworld().sayHello();
        
        /**
         * 顺带说明下 System.load 与 System.loadLibrary
         * 功能 :两个方法都是去加载dll库,
         * 区别 :System.load  根据文件目录和名称加载dll,
         * System.loadLibrary 是加载已知运行Path目录下的dll库,并且不能带后缀,
其实起运行的时候System.load 与 System.loadLibrary调用了 :    ClassLoader.loadLibrary(fromClass, filename, true);
         *
         */
    }
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: