浅谈Java的本地方法实现JNI

最近做了一个数据结构课上迷宫求解的问题,要求在栈结构上最好能带一个图形界面,将找到的迷宫路径展示出来。原本打算连图形界面一起用C语言写,但是C语言的图形界面如果不调用操作系统的图形库真的很难看,所以选择了Java写图形界面,C语言写算法的这样一个混合编程的方案。这里不对Java图形界面的具体实现和C的算法做解释,只介绍Java和C的“连接部分”。

使用本地方法的前提

虽然现在Java的执行效率的确得到了很大的提升,但是一旦遇到大量计算操作时,还是不如C语言执行快。这种情况下,我们可以考虑将关键的算法部分交给C语言去处理,而其余的部分由Java处理。

Java部分

Java中应对C语言中预期的函数进行声明,这里规定使用native关键字,如:

public static native void something();

采用这种native声明的方式,告知JVM这个方法的定义和具体实现在外部完成,JVM只负责唤醒这个C函数;之后编译这个文件。而在所有操作都完成后,还要向文件中添加static标记的域,如:

static{ System.loadLibrary(“Something”); }

然后再重新编译。前后总共编译两次。

C部分

至于C部分,因为是要让JVM调用C程序,所以首先要保证JVM能识别C程序——又因为JVM能识别的是Java格式,所以你的C代码要按照JVM能识别的样式编写。

这里我们用到了javah这个程序,这个程序帮助我们按照之前第一次编译好的本地方法类文件自动生成JVM期许样式的包含C函数声明的C头文件,之后我们要从这个头文件中复制函数声明到自己的C源文件中,作为C程序的入口(相当于正常C代码中的main函数)。

之后把这个所谓的“main”函数处理好后,其余的其他函数如果C程序不涉及与Java部分参数交互的话,就完全按照C语言标准编写。

连接操作

对于Java来讲,其运行在JVM上以实现跨平台能力。但对于C语言来说,却是紧紧依赖操作系统的。所以Java和C混合编程的结果就是受C语言的影响,Java的跨平台能力受到限制——这也是为什么JVM自身是有平台局限性的,而运行在JVM上的纯Java应用是跨平台的。既然收到操作系统的限制,也就不得不将Windows和Linux分开。

对于Linux,在得到头文件后,使用:

gcc -fPIC -I jdkPath/include -I jdkPath/include/linux -shared -o libname.so name.c

这条命令进行编译。之后将.so文件所在路径添加到库路径中。

而对于Windows,得到头文件后,虽然也可以通过cl(微软编译器)编译处理,但是用惯了图形IDE的人可能对命令行界面并不感冒。所以这里介绍使用图形IDE生成动态库文件的方法。

1)首先需要将Java安装目录下jdk/include中的jni.h和jdk/include/win32中的jni_md.h复制到相应C编辑器目录下的include目录中。include目录在Visual Studio中能直接找到,在Dev C++中在MinGW64这个子目录中。

2)之后用该编辑器建立一个DLL项目,在这个项目中编译C文件生成name.dll,将该dll复制到Eclipse(如果是Eclipse)相应Java项目的文件夹下即可;若不是,可复制到jdk/bin或jre/bin下。

但不管是Windows还是Linux,之后都要再回到Java项目相应本地类源文件,添加之前所说的static标记域,其中的Something是你的dll文件的名字。然后编译Java代码,运行。

原文地址:https://www.cnblogs.com/fusiji/p/11409864.html

时间: 2024-10-14 07:47:50

浅谈Java的本地方法实现JNI的相关文章

浅谈Java中的hashcode方法 - 海 子

浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个方法的声明可知,该方法返回一个int类型的数值,并且是本地方法,因此在Object类中并没有给出具体的实现. 为何Object类需要这样一个方法?它有什么作用呢?今天我们就来具体探讨一下hashCode方法. 一.hashCode方法的作用 对于包含容器类型的程

浅谈JAVA中的“hashcode()”方法

浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 为何Object类需要这样一个方法?它有什么作用呢?今天我们就来具体探讨一下hashCode方法. 根据这个方法的声明可知,该方法返回一个int类型的数值,并且是本地方法,因此在Object类中并没有给出具体的实现. 一.hashCode方法的作用 对于包含容器类型的程

java 本地方法(JNI)

最近搞了一个调用第三方so库做登录认证的任务,以前对JNI没什么概念,最近学习了 <java核心技术> 本地方法 一章,把自己写的一些例子记录一下. 自己C语言真是渣渣,所以所有的例子都在可以包括基本API的基础上尽可能简单.以下所有例子都是在centos 7中测试的,window不太熟. 调用本地方法 java调用本地方法,首先需要加载包含对应方法的so库(linux),一般使用下面这种方式加载so库. 1 public class Test{ 2 static 3 { 4 //so库的名字

浅谈java线程池

熟悉java多线程的朋友一定十分了解java的线程池,jdk中的核心实现类为java.util.concurrent.ThreadPoolExecutor.大家可能了解到它的原理,甚至看过它的源码:但是就像我一样,大家可能对它的作用存在误解...现在问题来了,jdk为什么要提供java线程池?使用java线程池对于每次都创建一个新Thread有什么优势? 对线程池的误解 很长一段时间里我一直以为java线程池是为了提高多线程下创建线程的效率.创建好一些线程并缓存在线程池里,后面来了请求(Runn

浅谈Java回收对象的标记和对象的二次标记过程_java - JAVA

文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 一.对象的标记 1.什么是标记?怎么标记? 第一个问题相信大家都知道,标记就是对一些已死的对象打上记号,方便垃圾收集器的清理. 至于怎么标记,一般有两种方法:引用计数和可达性分析. 引用计数实现起来比较简单,就是给对象添加一个引用计数器,每当有一个地方引用它时就加1,引用失效时就减1,当计数器为0的时候就标记为可回收.这种判断效率很高,但是很多主流的虚拟机并没有采用这种方法,主要是因为它很难解决几个对象之间循环引用的

浅谈Java中的深拷贝和浅拷贝

浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: [java] view plaincopyprint? int apples = 5; int pears = apples; int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short,float

浅谈java类集框架和数据结构(2)

继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主要有最重要的三种实现:ArrayList,Vector,LinkedList,三种List均来自AbstracList的实现,而AbstracList直接实现了List接口,并拓展自AbstractCollection. 在三种实现中,ArrayList和Vector使用了数组实现,可以认为这两个是

浅谈 Java Printing

浅谈 Java  Printing 其实怎么说呢?在写这篇博文之前,我对java printing 可以说是一无所知的.以至于我在敲文字时, 基本上是看着api文档翻译过来的.这虽然看起来非常的吃力,但是我相信,有道大哥不会辜负我的.嘻 嘻! Java Printing 技术,也就是我们平时所接触的打印,只不过是说可以用Java实现而已. 一.Java Printing 打印简介 Java Printing API能够使java应用程序实现相关的打印功能,如: 1.打印所有 Java 2D 和

【转】浅谈Java中的equals和==

浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str2 = new String("hello"); 3 4 System.out.println(str1==str2); 5 System.out.println(str1.equals(str2)); 为什么第4行和第5行的输出结果不一样?==和equals方法之间的区别是什么?如果在初