java jni编程之hello world

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值