欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-03-13 08:17:09
1. jni简介 jni是java native interface的英文缩写,意为java本地接口。 问题来源:由于java编写底层的应用较难实现,在一些实时性要求非...

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快速入门教程(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。