自己实现一个Native方法的调用

JNI

开始本篇的内容之前,首先要讲一下JNI。Java很好,使用的人很多、应用极广,但是Java不是完美的。Java的不足体现在运行速度要比传统的C++慢上许多之外,还有Java无法直接访问到操作系统底层如硬件系统,为此Java提供了JNI来实现对于底层的访问。JNI,Java Native Interface,它是Java的SDK一部分,JNI允许Java代码使用以其他语言编写的代码和代码库,本地程序中的函数也可以调用Java层的函数,即JNI实现了Java和本地代码间的双向交互。

Native

JDK开放给用户的源码中随处可见Native方法,被Native关键字声明的方法说明该方法不是以Java语言实现的,而是以本地语言实现的,Java可以直接拿来用。这里有一个概念,就是本地语言,本地语言这四个字,个人理解应该就是可以和操作系统直接交互的语言。

通过JNI调用C++写的代码

下面演示一下如何写一段简单的C++代码,在Java中用一个Native方法去调用的步骤。C++代码使用到的IDE是Microsoft Visual Studio 2010,这是一款市面上开发C++代码最常用的IDE,功能强大。OK,接下来一步一步演示一下:

1、写一段Java代码。由于我们在Windows环境下,所以用的是一个.dll文件,如果在Linux环境下的话,用的是一个.so文件。最后C++代码写完之后要生成一个.dll/.so文件,生成的文件可以使用static静态加载的方法加载进来,也可以通过配置环境变量的方式,这里选择前者。

 1 public class TestMain
 2 {
 3     static
 4     {
 5         System.load("D:" + File.separator + "Hello.dll");
 6     }
 7
 8     public native static void Hello();
 9
10     public static void main(String[] args)
11     {
12         Hello();
13     }
14 }

2、cmd进入命令行程序中,进入刚才写的那个类的CLASSPATH下,CLASSPATH就是.class文件所在的根路径。运行“JNI -jni com.xrq.test1.TestMain” ,表示为指定的类下的Native方法生成.h文件。.h文件是C/C++使用的头文件,用于将声明和实现分离,不熟悉C/C++的同学也不用深究

3、进入自己的CLASSPATH底下查看一下有没有多一个.h文件,我自己这边的是

这个命名是javah这个命令的实现帮我们命名的,只要多了这个文件就可以了

4、打开VS2010,文件-->新建-->项目,命名为“Hello”,和我们静态块中load进去的名字要一致

注意选择DLL

5、刚才通过javah生成的.h文件复制到Hello目录下

6、把这个.h添加到项目中,右键头文件-->添加-->现有项,选择Hello目录下的“com_xrq_test1_TestMain.h”添加进去就好了

7、右键源文件-->添加-->新建项,选择.cpp文件,随便命名,我叫做source.cpp。实现很简单,就打印一下“Hello”这个字符串。cout是C++的控制台输出语句,相当于Java的System.out.print(),endl是换行的意思,所以这整句相当于Java的System.out.println("Hello");

8、修改“com_xrq_test1_TestMain.h”头文件中的#include <jni.h>为#include "jni.h"

9、把%JAVA_HOME%/include目录下的“jni.h”%JAVA_HOME%/include/win32目录下的“jni_md.h”两个文件复制到Hello目录下,用刚才添加“com_xrq_test1_TestMain.h”一样的方式添加这两个.h文件到头文件目录中,这样目录下Hello目录下应该多出了两个文件,VS2010工程目录下应该有3个.h文件。JAVA_HOME就是JDK安装目录,不知道的cmd进入命令行,echo %JAVA_HOME%就可以查看了。这一步很重要,没有这一步,C++程序是无法运行的

10、右键项目-->生成,就可以生成.dll文件了

11、刚才生成的.dll文件是32系统下的,32系统的用户可以直接使用这个.dll文件了,只要复制到静态代码块指定的目录下就好了。换句话说,64位系统的用户是不能使用这个.dll文件的。如果要生成64位计算机可以使用的.dll文件,还要额外再为64位计算机成生一个.dll文件

下拉菜单里面没有x64的点击下拉菜单-->配置管理器配置一下,自己摸索一下就好了,VS2010有自带x64的

12、生成64位的.dll,复制到D盘下即可,也就是静态代码块里面指定的Hello.dll的路径

13、运行一下第一步里面写的Java程序,C++打印的“Hello”就出来了,至此,Java通过JNI调用C++编写的代码的功能完成。

有什么心得?

自己完成了这么一个过程,肯定是颇有成就感的,成就感过后,我们可以从这13个步骤中感悟到什么?至少个人有以下心得:

1、1个类中有很多Native方法-->这个类中的所有Native方法生成到1个.h文件中-->本地代码生成一个.dll/.so文件和一个类的Native方法实现相对应

2、为什么有Native方法的类中必有这么一段代码

1 private static native void ();
2 static {
3         registerNatives();
4     }

现在想来,估计和我们的静态代码块起的作用一样,都是为这个类导入特定的.dll/.so文件用的。至于为什么不能像我们这么写,个人猜测,是因为不同的用户磁盘上的.dll/.so文件位置不固定,和JDK安装目录相关?

3、Java不在乎Native方法是用什么语言实现的,只要一来语言能和底层打交道就好了,二来语言实现完可以提供出来.dll/.so文件。因此同一个Native方法,如果不同的Java虚拟机去调用它,那么结果可能都不同,比如Object的hashCode(),当然,运行效率也不尽然相同,因为不同的虚拟机对于不同的Native方法有自己的实现。

时间: 2024-08-02 11:03:45

自己实现一个Native方法的调用的相关文章

1217.2——定义一个类+方法声明调用

新建一个类 new file  ->cocoa class  (父类NSObject) .h文件 用来定义属性和方法 .m文件 用来具体实现 方法声明: 1 #import <Foundation/Foundation.h> 2 @interface Person : NSObject{ 3 NSString *name; 4 int age; 5 NSString *address; 6 } 7 -(void)useTools; //无参无返回值的方法声明 8 -(void)setNa

【java】详解native方法的使用

目录结构: contents structure [-] 关于native关键字 使用native关键字 使用步骤 案例 编写.java文件 编译.java文件 获得.h文件 编写hello.cpp文件 部署hello.dll文件 运行HelloWorld.class文件 参考文章 1,关于native关键字 想必读者已经了解过native关键字了.这里笔者就大致囊括一下,被native关键字修饰的方法叫做本地方法,本地方法和其它方法不一样,本地方法意味着和平台有关,因此使用了native的程序

java 里面的 native 方法

第一篇: 今天花了两个小时把一份关于什么是Native Method的英文文章好好了读了一遍,以下是我依据原文的理解. 一. 什么是Native Method   简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C.这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编译器去调用一个C的函数.   

Java的native方法

一. 什么是Native Method 简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C.这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编译器去调用一个C的函数.   "A native method is a Java method whose implementation is

Java中的native方法

博客引用地址:Java中的native方法 今天花了两个小时把一份关于什么是Native Method的英文文章好好了读了一遍,以下是我依据原文的理解. 一. 什么是Native Method 简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C.这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编

java Native 方法

一. 什么是Native Method   简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C.这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编译器去调用一个C的函数.   "A native method is a Java method whose implementation

Java OutOfMemoryError 的原因是什么,什么是Java native方法

Java OutOfMemoryError 的原因是什么,什么是Java native方法? 二.Java native方法转载的博文 第一篇: 今天花了两个小时把一份关于什么是Native Method的英文文章好好了读了一遍,以下是我依据原文的理解. 2.1 什么是Native Method   简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C.这个特征并非jav

java native interface JNI 调用Java方法

在上一篇文章中介绍了JNI,以及java调用JNI,这篇讲一下 JNI调用java方法. 通过使用合适的JNI函数,你可以创建Java对象,get.set 静态(static)和 实例(instance)的域,调用静态(static)和实例(instance)函数.JNI通过ID识别域和方法,一个域或方法的ID是任何处理域和方法的函数的必须参数. 下表列出了用以得到静态(static)和实例(instance)的域与方法的JNI函数.每个函数接受(作为参数)域或方法的类,它们的名称,符号和它们对

输入6个人的成绩放入到一个一维数组中,然后打印出平均分,最后按成绩 从大到小打印。三个功能(输入是一个函数,求平均分是一个函数,排序是一个 函数)都用函数实现,最后在main方法中调用。

/*5.输入6个人的成绩放入到一个一维数组中,然后打印出平均分,最后按成绩从大到小打印.三个功能(输入是一个函数,求平均分是一个函数,排序是一个函数)都用函数实现,最后在main方法中调用.*/ #include <stdio.h> int inputScore(){ int score; scanf("%d",&score); return score;} double avg(int scores[],int length){ int i,score = 0;