java jni编程之hello world

来源:互联网 发布:mysql 默认值约束 编辑:程序博客网 时间:2024/06/05 22:48

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);         *          */    }}



原创粉丝点击