java jni编程之hello world
2017-11-06 23:34
176 查看
JAVA 本机接口(JAVA native interface) 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代码:
使用javah.exe (命令在JDK bin目录下)生成头文件 ;
二、使用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 中的方法;
什么场合下应该使用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); * */ } }
相关文章推荐
- 在java中使用JNI来编程
- windows下java JNI编程技巧——JAVA调用c/c++(0)
- Windows Java JNI编程环境搭建
- Java与C++之JNI编程小结
- Java编程--关于JNI你应该知道的一切
- JNI编程—— 让C++和Java相互调用
- 【Android学习】JNI(Java Native Interface,java本地接口)编程
- 使用Java中的JNI技术将C/C++程序嵌入到Java代码中实现Hello World
- JNI编程 —— 让C 和Java相互调用 - android - 牛蹄印章
- windows下java JNI编程技巧——JAVA调用c/c++(1)
- windows下java JNI编程技巧——JAVA调用c/c++(2)
- DNK编程 JNI 之 javah
- java jni实现hello world
- IntelliJ IDEA平台下JNI编程(五)—本地C代码创建Java对象及引用
- 使用JNI进行混合编程:在Java中调用C/C++本地库
- JNI编程—— 让C++和Java相互调用
- java/android下JNI编程总结
- JAVA JNI配置教程 使用JAVA调用Native方法打印Hello World
- 如何使用JNI,实现Java本地编程
- JNI编程 —— 让C++和Java相互调用