较详细的JNI简介

在Java中,有时候我们不得不要去使用其他语言的代码,比如说:

1、你的应用需要访问系统的各个特性和设备,这些特性和设备通过java平台是无法访问的。

2、你已经有了大量的测试过和调试过的用另一种语言编写的代码,并且知道如何将其导出到所有的目标平台上。

3、通过基础测试,你已经发现所编写的Java代码比用其他语言编写的等价代码要慢得多。

Java平台有一个用于和本地C代码进行互操作的API,称为Java本地接口(JNI)。现在就开始学习JNI,先从这篇的一个最简单的例子,了解如何使用JNI调用本地方法。

调用本地方法,打印出HelloWorld的步骤示例

1、在类中声明一个本地方法

package com.tao.test;
public class NativeTest {
 public static native void sayHello();
} 

我们使用native关键字,声明了一个本地方法,而且我们还将他声明为static。本地方法可以是静态的,也可以不声明为静态的。

2、编译.java文件,生成 含有该本地方法的类的字节码

如果是在eclipse中,进入<工程目录>\bin\com\tao\test,就可以找到eclipse自动为我们编译的.class文件。

如果不是,则进入进入NativeTest.java文件所在的目录,使用javac命令编译该java类,生成了NativeTest.class字节码。

3、使用javah命令编译.class字节码,生成包含native方法声明的C/C++头文件

如果是在eclipse中,进入<工程目录>\bin目录,然后使用下面的编译命令(如果不是eclipse,则根据上面编译生成的.class文件的位置来用javap编译)

1.javah com.tao.test.NativeTest   //记住要使用类型的全限定名称  

就会在bin目录下,生成我们需要的C\C++头文件   com_tao_test_NativeTest.h (头文件的名字带包名,且用_ 分隔),里面内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_tao_test_NativeTest */ 

#ifndef _Included_com_tao_test_NativeTest
#define _Included_com_tao_test_NativeTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:  com_tao_test_NativeTest
 * Method: sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_tao_test_NativeTest_sayHello
 (JNIEnv *, jobject); 

#ifdef __cplusplus
}
#endif
#endif 

4、按照生成的C/C++头文件来写C/C++源文件,并编译为DLL动态链接库

我们之前得到了包含native方法声明的C/C++头文件,现在我们按照这个头文件,编写我们的C\C++源文件,并编译为DLL动态链接库。

上一步,我们得到了com_tao_test_NativeTest.h头文件。

①、首先。新建一个Win32 DLL项目(我使用的是VS2005开发环境,VC6.0++是新建一个Win32 Dynamic-Link Library)

新建——>项目——>Visual C++——>Win32——>控制台应用程序——>输入项目名称,我使用为NativeCall

点击确定后,进入下面的界面

点击下一步,进入下一界面,勾选为DLL和空项目。

这样就建立了一个Win32 DLL项目了。

②、添加com_tao_test_NativeTest.h头文件

将com_tao_test_NativeTest.h头文件复制,黏贴到NativeCall/NativeCall/目录下,如E:\VCProject\NativeCall\NativeCall该文件夹。然后再VS2005中的项目中,添加该头文件

③、添加jni.h和

打开com_tao_test_NativeTest.h头文件,看第二行,调用了 jni.h,这个头文件需要我们自己添加,为了JAVA_HOME/include目录下,添加方式和第②步一样

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_tao_test_NativeTest */
#ifndef _Included_com_tao_test_NativeTest
#define _Included_com_tao_test_NativeTest 

然后把上面的第二行的 #include <jni.h>改为#include “jni.h“。让它去调用我们自己的头文件,而不是系统的头文件。

打开jni.h,我们可以找打这么一行

1.#include "jni_md.h"  

这个头文件也要我们自己添加,它位于JAVA_HOME/include/win32目录中,添加方式和前面一致。

④、编写源文件。

新建一个源文件,命名为NativeMethod

然后,在里面添加下面代码:

#include "com_tao_test_NativeTest.h" //引入头文件
#include <iostream>
using namespace std;
 JNIEXPORT void JNICALL Java_com_tao_test_NativeTest_sayHello //本地方法的实现
(JNIEnv * env, jobject obj)
{
 cout<<"hello World!"<<endl;
} 

最后,保存,运行,编译生成DLL文件,在工程项目的Debug目录中可以找到。

5、将DLL文件放入到PATH环境变量下。

复制DLL文件所在路径,加入到PATH环境变量下。

6、在java中调用我们这个本地方法

public class NativeTest {
 static{
  System.loadLibrary("NativeCode");
 }
 public native void sayHello();
 public static void main(String[] args) {
  new NativeTest().sayHello();
 }
} 

注意:

1、一般在static代码块中加载动态链接库

2、如果将DLL路径加入PATH环境变量的时候,eclipse是开着的,那么要关闭eclipse再开,让eclipse重新读取环境变量

3、必须在本类中使用native方法

下图表示了我们编写JNI的过程

总结

以上所述是小编给大家介绍的较详细的JNI简介,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 从源码编译Android系统的Java类库和JNI动态库的方法

    利用源码编译Android系统Java类库 1.编写Java项目和Android.mk文件 ├── Android.mk └── src └── com └── lhw └── framework └── led └── Led.java Led.java文件 package com.lhw.framework.led; /** * LED操作库 * @author Micky Liu */ public class Led { public boolean turnOn() { return

  • 启动 Eclipse 弹出 Failed to load the JNI shared library jvm.dll 错误的解决方法

    错误如下图所示: 有时候,新电脑上回碰到打开Eclipse时,弹出提示"Failed to load the JNI shared library jvm.dll"错误,这里给大家分享解决方案. 通常情况下,如果你是64位的系统,却安装了32位的JDK,就会导致上面的情况. 解决办法 1.卸载掉原来安装的32位的JDK,然后安装64位的JDK到电脑中. 2.重新修改path 和 classpath 两个环境变量.因为在64系统当中,32位软件回安装到program files (*86

  • Ubuntu 使用Jni开发实例详解

    1. 编写Java文件,在其中声明native方法, 并通过static 语句块加载动态链接库,示例Prompt.java代码如下: class Prompt { private native String getLine(String prompt); public static void main(String args[]) { Prompt p = new Prompt(); String input = p.getLine("Type a line: "); System.o

  • Android通过JNI实现守护进程

    开发一个需要常住后台的App其实是一件非常头疼的事情,不仅要应对国内各大厂商的ROM,还需要应对各类的安全管家...虽然不断的研究各式各样的方法,但是效果并不好,比如任务管理器把App干掉,服务就起不来了... 网上搜寻一番后,主要的方法有以下几种方法,但都是治标不治本: 1.提高Service的优先级:这个,也只能说在系统内存不足需要回收资源的时候,优先级较高,不容易被回收,然并卵... 2.提高Service所在进程的优先级:效果不是很明显 3.在onDestroy方法里重启service:

  • Java的JNI快速入门教程(推荐)

    1. JNI简介 JNI是Java Native Interface的英文缩写,意为Java本地接口. 问题来源:由于Java编写底层的应用较难实现,在一些实时性要求非常高的部分Java较难胜任(实时性要求高的地方目前还未涉及,实时性这类话题有待考究). 解决办法:Java使用JNI可以调用现有的本地库(C/C++开发任何和系统相关的程序和类库),极大地灵活Java的开发. 2. JNI快速学习教程 2.1 问题: 使用JNI写一段代码,实现string_Java_Test_helloworld

  • 较详细的JNI简介

    在Java中,有时候我们不得不要去使用其他语言的代码,比如说: 1.你的应用需要访问系统的各个特性和设备,这些特性和设备通过java平台是无法访问的. 2.你已经有了大量的测试过和调试过的用另一种语言编写的代码,并且知道如何将其导出到所有的目标平台上. 3.通过基础测试,你已经发现所编写的Java代码比用其他语言编写的等价代码要慢得多. Java平台有一个用于和本地C代码进行互操作的API,称为Java本地接口(JNI).现在就开始学习JNI,先从这篇的一个最简单的例子,了解如何使用JNI调用本

  • 浅谈将JNI库打包入jar文件

    在Java开发时,我们有时候会接触到很多本地库,这样在对项目打包的时候我们不得不面临一个选择:要么将库文件与包好的jar文件放在一起:要么将库文件包入jar. 将一个不大的项目包成一个jar有诸多发布优势,本次将分享一个将JNI包入jar的方法. [实现思路] 将JNI库(dll.so等)包入jar后,我们无法通过路径来访问它们,而库的读取依赖一个java.library.path下对应名称的外部库文件,我们仅仅需要在调用JNI前将其由jar包释放出来,这类似于文件的拷贝过程. [部署位置的选取

  • JNI语言基本知识

    JNI简介 JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++).从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了.使用java与本地已编译的代码交互,通常会丧失平台可移植性.但是,有些情况下这样做是可以接受的,甚至是必须的.例如,使用一些旧的库,

  • Java使用jni清屏功能的实现(只针对cmd)

    JNI简介 JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++).从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了.使用java与本地已编译的代码交互,通常会丧失平台可移植性.但是,有些情况下这样做是可以接受的,甚至是必须的.例如,使用一些旧的库,

  • Android NDK开发的环境搭建与简单示例

    一.NDK与JNI简介 NDK全称为native development kit本地语言(C&C++)开发包.而对应的是经常接触的Android-SDK,(software development kit)软件开发包(只支持java语言开发). 简单来说利用NDK,可以开发纯C&C++的代码,然后编译成库,让利用Android-SDK开发的Java程序调用.NDK开发的可以称之为底层开发或者jni(java native interface)层开发,SDK开发可以称为上层开发. Andro

  • Python 虚拟环境工作原理解析

    目录 简介 使用 激活脚本 工作原理 关于 sys.prefix 总结 其它 Python 的虚拟环境用来创建一个相对独立的执行环境,尤其是一些依赖的三方包,最常见的如不同项目依赖同一个但是不同版本的三方包,而且,在虚拟环境中的安装包不会影响到系统的安装包. 不过,其具体的工作原理是怎样的,这里详细介绍. 简介 几乎每个语言都包含自己的包管理工具,这是一个非常复杂的话题,而不同语言选择的实现又略有区别,都会做一些选择和取舍.而 Python 的包管理解决方案很多,例如 pip.virtualen

  • DOS批处理脚本语言简介与详细说明

    一.简单批处理内部命令简介 1.Echo 命令 打开回显或关闭请求回显功能,或显示消息.如果没有任何参数,echo 命令将显示当 前回显设置. 语法 echo [{on off}] [message] Sample:@echo off / echo hello world 在实际应用中我们会把这条命令和重定向符号(也称为管道符号,一般用> >> ^)结 合来实现输入一些命令到特定格式的文件中.这将在以后的例子中体现出来. 2.@ 命令 表示不显示@后面的命令,在入侵过程中(例如使用批处理

  • JAVA JNI函数的注册过程详细介绍

    JAVA JNI函数的注册过程详细介绍 我们在java中调用Native code的时候,一般是通过JNI来实现的,我们只需要在java类中加载本地.so库文件,并声明native方法,然后在需要调用的地方调用即可,至于java中native方法的具体实现,全部交给了Native层.我们要在java中正确地调用到本地代码中对应函数的前提是什么呢?答案就是通过一定的机制建立java中native方法和本地代码中函数的一一对应关系,那么这种机制是什么呢?就是JNI函数的注册机制. JNI函数的注册有

  • Visual Studio Code 从简介、安装到配置所需插件详细介绍

    提到visualstudiocode,想必你也听说过visualstudio(vs) 那就从查阅过的资料大致总结以下几点,关于这两个产品的区别: 首先总的来看,它们都是微软公司的产品 名字不一样当然会有不一样的用法或者解释 区别: ①先来介绍vs,它是微软公司开发发工具包系列产品,是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具.代码管控工具.集成开发环境(IDE)等.通俗的讲,是一款编译器. 而vscode是微软公司的一个项目,是针对于编写现代web和云应

随机推荐