java JNI 的实现(1)-又进一步加深对JVM实现的理解
目录
1,在eclipse的 'java类' 中声明一个 'native方法';
2,使用 'javah' 命令生成包含'native方法' 定义的 'C/C++头文件';
3,使用 'C/C++' 来实现以上生成的 'C/C++头文件' 中的方法;
5,在eclipse中将 '.dll动态链接库所在路径' 加入eclipse中的 'classpath';
6,在eclipse中的java类中加载.dll并调用native方法.
概述
其实细心点的程序员应该注意到,java的源码中,方法的实现,要么是具体实现,要么是定义为native.而定义为native的方法则交给诸如C之类等语言,在具体的操作系统上去实现.我们知道java是通过JVM运行的,而JVM多是通过C和汇编实现的.我们可以猜测,具体就是通过强大的sun提供的JNI这个桥梁去实现.
我们也因此知道,为什么每一种操作系统,对应不同的JVM,其实就是JNI的具体实现是非跨平台引起的.
关于JNI调用 的一些过程,大体上还算理解了点.
主要优点:
- java语言调用其他语言(如,C/C++)的实现.这个有时确实算是需要的,比如java需要调用一种方法(这个方法的算法很难,但是已经由非java语言写的,而且你很急,如果要用java实现,会花很多开发成本).
- 高性能,这个我一开始不是很明白,其实JNI的实现,能使用旧的库,使用一些依赖于机器语言交换,这自然就提高了性能了.
主要缺点:
- 从上面的第2点,暴漏了很明显的缺点,我们在使用JNI进行与操作系统等直接交互,或很依赖机器或硬件的时,自然可移植就丧失了.所以JNIj是ava的一部分,但是要慎用,比较,java是因其跨平台而出名的.也就是说,如果这个程序(基于JNI的)需要跨平台,则native方法声明的具有实现,需要重新修改(这是一个开发成本的开销).
- 使用JNI还有一个优点,就是,java是强类型语言,是一种编译型语言,而C/C++不是,所以在开发时需要很小心,毕竟C/C++这类语言之间操作内存,是非安全的.
JNI实现的简单例子
下面说明一下,如何使用一个简单的JNI程序,好进一步理解JNI:
开发工具:
1,JDK v1.7.0_71(x64);
2,Eclipse Java EE IDE for Web Developers(Indigo Release),即eclipse v3.7.0;
3,Visual Studio 2013 express(x86);
4,我的操作系统是win7旗舰版SP1(x64).
简略步骤:
1,在eclipse的 'java类' 中声明一个 'native方法';
2,使用 'javah' 命令生成包含'native方法' 定义的 'C/C++头文件';
3,使用 'C/C++' 来实现以上生成的 'C/C++头文件' 中的方法;
4,将实现的文件编译为 '.dll'动态链接库;
5,在eclipse中将 '.dll动态链接库所在路径' 加入eclipse中的 'classpath';
6,在eclipse中的java类中加载.dll并调用native方法.
具体步骤:
1,在eclipse中新建一个名为 'SayHello' 的Java Project,添加一个全名为'juk.demo.SayHello'的类,代码为:
package juk.demo;
public class SayHello {
public native void SayHello();
public static void main(String[] args) {
}
}
2,通过 'cmd' 打开命令行窗口,进入'SayHello'根目录下的'bin'目录,使用 'javah juk.demo.SayHello'命令生成包含'native方法' 定义的 'C/C++头文件';
3,A,打开VS2013,通过'File->New Project'打开'New Project'对话框,选择左侧的'Templates/Visual C++/Win32',然后选择'Win32 Project',输入名为'CppSay'的项目名,选择合适的路径,确定.B,在 'Solution Explore'视图下,在'CppSay'项目上右键,选择'Open Folder in File Explore',并将以上第一步生成的 'C/C++头文件'放入与 'CppSay.vcxproj' 同级的目录下.同理,将JDK安装目录下的 'include\jni.h' 和 'include\win32\jni_md.h'(例如'H:\Program Files\Java\jdk1.7.0_71\include\jni.h' 和 'H:\Program Files\Java\jdk1.7.0_71\include\win32'),加入同样的目录中.C,在'Solution Explore'视图的 'Header Files' 上右键,选择"Add->Existing Item"引入刚添加的3个 .h头文件.在'Solution Explore'视图的 'Source Files'上添加一个 '.cpp文件,实现java定义的native方法(通过机器生成的函数原型),代码为:
#include <iostream>
#include "juk_demo_SayHello.h"
using namespace std; //(函数原型在"juk_demo_SayHello.h"中)在C/C++中实现通过javah 产生的头文件的函数(或者说在C/C++中实现java定义的native方法).
JNIEXPORT void JNICALL Java_juk_demo_SayHello_SayHello
(JNIEnv * env, jobject obj) {
cout<<"hello, java native interface"<<endl;
}
4,将VS2013 'Standard'工具条中的'Solution Platform'修改为'x64'(因为我的JDK是x64),不然在java中加载dll的时候会报错:Can't load IA 32-bit .dll on a AMD 64-bit platform,然后编译整个项目,会在'解决方案'的 'x64'目录中的Debug目录下,产生'CppSay.dll'动态链接库(注意是解决方案下的Debug,而不是项目下的Debug),目录如'C:\Users\Administrator\Documents\visual studio 2012\Projects\CppSay\x64\Debug'
5,在eclipse的'SayHello'项目下的 'JRE System Library'上右键,选择 'Build Path'->'Config Build Path',选择 'Java Build Path'下的'JRE System Library'中的 'Native library location',点击右侧的'Edit',将上面第4步产生'CppSay.dll'的目录选中,即完成classpath的配置.
6,在第1步中的Java类中,定义一个静态代码块,使用:
System.loadLibrary("CppSay")
加载动态链接库(也可以不通过静态代码块),注意的是,名称不能包含'.dll',否则会报错: java.lang.UnsatisfiedLinkError: no CppSay.dll in java.library.path,运行eclipse的'SayHello'项目,会在控制台上输出: 'hello, java native interface'.
JNI的简单使用就是这样了.
java JNI 的实现(1)-又进一步加深对JVM实现的理解的更多相关文章
- java JNI 的实现(2)-java和C/C++的相互调用.
目录 概述 一,java代码 二,稍微注意通过javah生成的'C/C++'.h头文件和源java代码的关系 三,在C/C++中实现java的native方法(完整C/C++) 1,修改age,即Ja ...
- 学JAVA第十八天,接口与抽象类进一步加深
昨天老师讲了建网站,还要交钱买东西的,所以就没写,今天讲了接口与抽象类进一步加深 上完今天的课后,我才知道一个接口可以有多个实现类,一个实现类可以同时接多个接口. 现在就用代码来解释吧!!! 举例用人 ...
- java + jni + mingw实例开发(基于命令行窗口模式)
java+ jni + mingw 参考网址: http://wenku.baidu.com/link?url=9aQ88d2ieO7IgKLlNhJi5d3mb3xwzbezLPzSIX3ixz4_ ...
- 三、Android NDK编程预备之Java jni入门创建C/C++共享库
转自: http://www.eoeandroid.com/thread-264971-1-1.html 应网友回复,答应在两天前要出一篇创建C/C++共享库的,但由于清明节假期,跟朋友出去游玩,丢手 ...
- 二、Android NDK编程预备之Java jni入门Hello World
转自: http://www.eoeandroid.com/forum.php?mod=viewthread&tid=264543&fromuid=588695 昨天已经简要介绍了J ...
- 一、Android NDK编程预备之Java jni简介
转自: http://www.eoeandroid.com/thread-264384-1-1.html 游戏开发 视频教程 博客 淘帖 论坛›eoe·Android应用开发区›Androi ...
- java JNI 调试出现的错误
java JNI 调试出现的错误 ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2JDW ...
- JAVA JNI学习
JAVA JNI JNI是Java Native Interface的缩写,中文为JAVA本地调用.从Java1.1开始,Java Native Interface(JNI)标准成为java平台的 ...
- JAVA JNI
jni非常好的一篇文章 http://m.blog.csdn.net/article/details?id=22827307 JAVA JNI介绍 http://blog.csdn.net/cyg08 ...
随机推荐
- python使用platform模块获取系统环境并去除换行符
近来在porting一个网站,企图拿到这个网站的数据来做分析.为了支持多系统环境的正常运行.需要知道当前系统环境的是什么OS? 1.python内置platform库.可以很方便得到当前系统环境时什么 ...
- postgres常用类型
数值类型 名字 存储空间 描述 范围 smallint 2 字节 小范围整数 -32768 到 +32767 integer 4 字节 常用的整数 -2147483648 到 +2147483647 ...
- windows下Django 部署到Apache24的配置
1.首先下载最新版Apachehttp://httpd.apache.org/download.cgi#apache24,目前官方以不提供windows msi安装包,下载好的直接解压至C盘即可,ap ...
- Swift互用性:与 Objective-C 的 API 交互(Swift 2.0版更新)-备
本页包含内容: 初始化 可失败初始化 访问属性 方法 id 兼容性(id Compatibility) 空值和可选值 扩展(Extensions) 闭包(Closures) 比较对象 Swift 类型 ...
- asp.net(C#)写SQL语句技巧
/*添加SQL*/string fields = "";string values = "";fields += "xm"; values ...
- 转:PHP乱码问题,UTF-8(乱码)
原文来自于:http://www.cnblogs.com/rickyNote/archive/2012/04/09/2438704.html 一.HTML页面转UTF-8编码问题 1.在head后,t ...
- 嵌入式linux加载引导内核和根文件系统的方法
总体来说,嵌入式Linux内核和根文件的引导与PC机差不多.嵌入式linux内核和根文件系统可以存放在各种可能的存储设备中,一般情况下我 们将内核和根文件系统直接烧入到Flash中(包括NOR和NAN ...
- 读取word文件.选择了TextParse
待续! 代码还没分离出来.. 分离后会上传上来 不支持wps 文件 . ]]>
- led驅動芯片對LED燈具的要求
1.LED驅動芯片直流額定輸入電壓范圍應當8 - 40 v,覆蓋廣泛的應用需求.最好的壓縮能力大于45 v.當輸入交流12 v.24 v,簡單的橋式整流器輸出電壓可以遵循電網電壓波動,特別是在高電壓輸 ...
- LaTeX排版工具使用
专业的论文,都是用Latex.CTex等相关的工具.那么,用word写论文,缺点在哪? latex 写的东西,最终要编译成pdf格式的.里面的格式,尤其是数学类符号等,比较漂亮.这是word不能比的. ...