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(JNIEnv *env, jclass cls , jstring j_str)函数,实现在字符串j_str("world")前面加上hello,并返回。

2.2 解决问题过程:

I. 编写Test.java类:

public class Test{
  // native interface
  public native String helloworld(String text);

  public static void main(String[] args){
    // Load dynamic library
    System.loadLibrary("Test2");
    Test ts = new Test();
    String text = ts.helloworld("world");
    System.out.println(text);
  }
}

备注:

1、加载动态类库:System.loadLibrary("Test2");【Windows下加载的就是Test2.dll,Linux下加载的是Test2.so】

II. 编译Test.java文件

进入cmd输入命令 > javac Test.java

III. 生成Test.h文件

进入cmd输入命令 > javah Test

Test.h文件内容如下:

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

#ifndef _Included_Test
#define _Included_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:   Test
 * Method:  helloworld
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_Test_helloworld
 (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

备注:

1、函数声明,固定格式:JNIEXPORT;返回类型:jstring;JNI调用:JNICALL;Java_完整类名_方法名:Java_Test_helloworld;

2、函数参数:调用jni.h封装好的函数指针:JNIEnv;Java类本身:jobject,Java文件传入参数:jstring。

IV. 编写C语言文件Test2.c实现Test类调用动态链接库的功能:

#include "Test.h"
#include <string.h>

JNIEXPORT jstring JNICALL Java_Test_helloworld
 (JNIEnv *env, jobject obj, jstring string){
  const char* str = (*env)->GetStringUTFChars(env,string,0);
  char cap[128];
  cap[0] = 'h';
  cap[1] = 'e';
  cap[2] = 'l';
  cap[3] = 'l';
  cap[4] = 'o';

  strcat(cap,str);

  (*env)->ReleaseStringUTFChars(env,string,0);
  return (*env)->NewStringUTF(env,cap);
 }

备注:

1、由于Java本身使用了双字节字符,C语言本身都是单字节字符,所以需要使用(*env)->GetStringUTFChars()转换Java和C之间的字符串;

2、GetStringUTFChars()和NewStringUTF(),第一个是从UTF8转换为C的编码格式,第二个是根据C的字符串返回一个UTF8字符串;

3、ReleaseStringUTFChars()是用来释放对象的,在Java中有虚拟机进行垃圾回收,但是在C语言中这些对象必须手动回收,否则可能造成内存泄漏。

V. 编译和运行

编译:

进入cmd输入命令 > gcc -I "D:\Program Files\Java\jdk1.8.0_45\include" -I "D:\Program Files\Java\jdk1.8.0_45\include\win32" --share Test2.c -o Test2.dll

运行:

进入cmd输入命令 > java Test

运行结果如下:

helloworld

3. 总结:

第一步:编写带有native方法的Java类(Test.java),使用javac工具编译Java类(生成Test.class);

第二步:使用javah生成与native方法对应的头文件(Test.h);

第三步:使用C/C++实现相应的头文件(Test2.c),并编译为动态链接库(Test2.so)。

本文运行环境:Windows 64位操作系统,JDK 1.8版本,mingw64(GCC)。

以上这篇Java的JNI快速入门教程(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

时间: 2016-09-04

启动 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:

从源码编译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

较详细的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

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和云应

JAVA JNI原理详细介绍及简单实例代码

JAVA JNI原理 JNI是JAVA标准平台中的一个重要功能,它弥补了JAVA的与平台无关这一重大优点的不足,在JAVA实现跨平台的同时,也能与其它语言(如C.C++)的动态库进行交互,给其它语言发挥优势的机会. 有了JAVA标准平台的支持,使JNI模式更加易于实现和使用.在此总结了下面这个知识图: 实例: 环境说明:ubuntu 10.4.2 LTS系统 程序清单1:src/com/magc/jni/HelloWorld.java /** * */ package com.magc.jni;