Java的JNI快速入門(mén)教程(推薦)
1. JNI簡(jiǎn)介
JNI是Java Native Interface的英文縮寫(xiě),意為Java本地接口。
問(wèn)題來(lái)源:由于Java編寫(xiě)底層的應(yīng)用較難實(shí)現(xiàn),在一些實(shí)時(shí)性要求非常高的部分Java較難勝任(實(shí)時(shí)性要求高的地方目前還未涉及,實(shí)時(shí)性這類(lèi)話題有待考究)。
解決辦法:Java使用JNI可以調(diào)用現(xiàn)有的本地庫(kù)(C/C++開(kāi)發(fā)任何和系統(tǒng)相關(guān)的程序和類(lèi)庫(kù)),極大地靈活Java的開(kāi)發(fā)。
2. JNI快速學(xué)習(xí)教程
2.1 問(wèn)題:
使用JNI寫(xiě)一段代碼,實(shí)現(xiàn)string_Java_Test_helloworld(JNIEnv *env, jclass cls , jstring j_str)函數(shù),實(shí)現(xiàn)在字符串j_str("world")前面加上hello,并返回。
2.2 解決問(wèn)題過(guò)程:
I. 編寫(xiě)Test.java類(lèi):
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、加載動(dòng)態(tài)類(lèi)庫(kù):System.loadLibrary("Test2");【W(wǎng)indows下加載的就是Test2.dll,Linux下加載的是Test2.so】
II. 編譯Test.java文件
進(jìn)入cmd輸入命令 > javac Test.java
III. 生成Test.h文件
進(jìn)入cmd輸入命令 > javah Test
Test.h文件內(nèi)容如下:
/* 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、函數(shù)聲明,固定格式:JNIEXPORT;返回類(lèi)型:jstring;JNI調(diào)用:JNICALL;Java_完整類(lèi)名_方法名:Java_Test_helloworld;
2、函數(shù)參數(shù):調(diào)用jni.h封裝好的函數(shù)指針:JNIEnv;Java類(lèi)本身:jobject,Java文件傳入?yún)?shù):jstring。
IV. 編寫(xiě)C語(yǔ)言文件Test2.c實(shí)現(xiàn)Test類(lèi)調(diào)用動(dòng)態(tài)鏈接庫(kù)的功能:
#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本身使用了雙字節(jié)字符,C語(yǔ)言本身都是單字節(jié)字符,所以需要使用(*env)->GetStringUTFChars()轉(zhuǎn)換Java和C之間的字符串;
2、GetStringUTFChars()和NewStringUTF(),第一個(gè)是從UTF8轉(zhuǎn)換為C的編碼格式,第二個(gè)是根據(jù)C的字符串返回一個(gè)UTF8字符串;
3、ReleaseStringUTFChars()是用來(lái)釋放對(duì)象的,在Java中有虛擬機(jī)進(jìn)行垃圾回收,但是在C語(yǔ)言中這些對(duì)象必須手動(dòng)回收,否則可能造成內(nèi)存泄漏。
V. 編譯和運(yùn)行
編譯:
進(jìn)入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
運(yùn)行:
進(jìn)入cmd輸入命令 > java Test
運(yùn)行結(jié)果如下:
helloworld
3. 總結(jié):
第一步:編寫(xiě)帶有native方法的Java類(lèi)(Test.java),使用javac工具編譯Java類(lèi)(生成Test.class);
第二步:使用javah生成與native方法對(duì)應(yīng)的頭文件(Test.h);
第三步:使用C/C++實(shí)現(xiàn)相應(yīng)的頭文件(Test2.c),并編譯為動(dòng)態(tài)鏈接庫(kù)(Test2.so)。
本文運(yùn)行環(huán)境:Windows 64位操作系統(tǒng),JDK 1.8版本,mingw64(GCC)。
以上這篇Java的JNI快速入門(mén)教程(推薦)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Java通過(guò)JNI 調(diào)用動(dòng)態(tài)鏈接庫(kù)DLL操作
- java通過(guò)jni調(diào)用opencv處理圖像的方法
- Java通過(guò)調(diào)用C/C++實(shí)現(xiàn)的DLL動(dòng)態(tài)庫(kù)——JNI的方法
- JNI實(shí)現(xiàn)最簡(jiǎn)單的JAVA調(diào)用C/C++代碼
- JAVA JNI原理詳細(xì)介紹及簡(jiǎn)單實(shí)例代碼
- JAVA JNI函數(shù)的注冊(cè)過(guò)程詳細(xì)介紹
- 從源碼編譯Android系統(tǒng)的Java類(lèi)庫(kù)和JNI動(dòng)態(tài)庫(kù)的方法
- 解析Java的JNI編程中的對(duì)象引用與內(nèi)存泄漏問(wèn)題
- java jni調(diào)用c函數(shù)實(shí)例分享(java調(diào)用c函數(shù))
- 詳解JNI到底是什么
相關(guān)文章
SpringMVC記錄我遇到的坑_AOP注解無(wú)效,切面不執(zhí)行的解決
這篇文章主要介紹了SpringMVC記錄我遇到的坑_AOP注解無(wú)效,切面不執(zhí)行的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
如何利用Java8 Stream API對(duì)Map按鍵或值排序
這篇文章主要給大家介紹了關(guān)于如何利用Java8 Stream API對(duì)Map按鍵或值排序的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用Java8具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
使用spring aop 統(tǒng)一捕獲異常和寫(xiě)日志的示例demo
本文通過(guò)一個(gè)小demo給大家介紹spring AOP 實(shí)現(xiàn)的異常捕獲和日志的方法技巧,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-08-08
js判斷是否是移動(dòng)設(shè)備登陸網(wǎng)頁(yè)的簡(jiǎn)單方法
這篇文章主要介紹了js判斷是否是移動(dòng)設(shè)備登陸網(wǎng)頁(yè)的簡(jiǎn)單方法,需要的朋友可以參考下2014-02-02
Java Map接口及其實(shí)現(xiàn)類(lèi)原理解析
這篇文章主要介紹了Java Map接口及其實(shí)現(xiàn)類(lèi)原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
如何在 Java 中實(shí)現(xiàn)不可變類(lèi)
這篇文章主要介紹了如何在 Java 中實(shí)現(xiàn)不可變類(lèi),不變性是函數(shù)式編程的關(guān)鍵,因?yàn)樗c盡量減少變化部分的這一目標(biāo)相一致,這使得對(duì)這些部分的推斷更為容易一些。,需要的朋友可以參考下2019-06-06

