Java的JNI快速入門教程(推薦)
1. JNI簡介
JNI是Java Native Interface的英文縮寫,意為Java本地接口。
問題來源:由于Java編寫底層的應(yīng)用較難實現(xiàn),在一些實時性要求非常高的部分Java較難勝任(實時性要求高的地方目前還未涉及,實時性這類話題有待考究)。
解決辦法:Java使用JNI可以調(diào)用現(xiàn)有的本地庫(C/C++開發(fā)任何和系統(tǒng)相關(guān)的程序和類庫),極大地靈活Java的開發(fā)。
2. JNI快速學(xué)習(xí)教程
2.1 問題:
使用JNI寫一段代碼,實現(xiàn)string_Java_Test_helloworld(JNIEnv *env, jclass cls , jstring j_str)函數(shù),實現(xiàn)在字符串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、加載動態(tài)類庫:System.loadLibrary("Test2");【W(wǎng)indows下加載的就是Test2.dll,Linux下加載的是Test2.so】
II. 編譯Test.java文件
進入cmd輸入命令 > javac Test.java
III. 生成Test.h文件
進入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;返回類型:jstring;JNI調(diào)用:JNICALL;Java_完整類名_方法名:Java_Test_helloworld;
2、函數(shù)參數(shù):調(diào)用jni.h封裝好的函數(shù)指針:JNIEnv;Java類本身:jobject,Java文件傳入?yún)?shù):jstring。
IV. 編寫C語言文件Test2.c實現(xiàn)Test類調(diào)用動態(tài)鏈接庫的功能:
#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語言本身都是單字節(jié)字符,所以需要使用(*env)->GetStringUTFChars()轉(zhuǎn)換Java和C之間的字符串;
2、GetStringUTFChars()和NewStringUTF(),第一個是從UTF8轉(zhuǎn)換為C的編碼格式,第二個是根據(jù)C的字符串返回一個UTF8字符串;
3、ReleaseStringUTFChars()是用來釋放對象的,在Java中有虛擬機進行垃圾回收,但是在C語言中這些對象必須手動回收,否則可能造成內(nèi)存泄漏。
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
運行結(jié)果如下:
helloworld
3. 總結(jié):
第一步:編寫帶有native方法的Java類(Test.java),使用javac工具編譯Java類(生成Test.class);
第二步:使用javah生成與native方法對應(yīng)的頭文件(Test.h);
第三步:使用C/C++實現(xiàn)相應(yīng)的頭文件(Test2.c),并編譯為動態(tài)鏈接庫(Test2.so)。
本文運行環(huán)境:Windows 64位操作系統(tǒng),JDK 1.8版本,mingw64(GCC)。
以上這篇Java的JNI快速入門教程(推薦)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
- Java通過JNI 調(diào)用動態(tài)鏈接庫DLL操作
- java通過jni調(diào)用opencv處理圖像的方法
- Java通過調(diào)用C/C++實現(xiàn)的DLL動態(tài)庫——JNI的方法
- JNI實現(xiàn)最簡單的JAVA調(diào)用C/C++代碼
- JAVA JNI原理詳細介紹及簡單實例代碼
- JAVA JNI函數(shù)的注冊過程詳細介紹
- 從源碼編譯Android系統(tǒng)的Java類庫和JNI動態(tài)庫的方法
- 解析Java的JNI編程中的對象引用與內(nèi)存泄漏問題
- java jni調(diào)用c函數(shù)實例分享(java調(diào)用c函數(shù))
- 詳解JNI到底是什么
相關(guān)文章
springboot后端接收前端傳數(shù)組參數(shù)三種方法
這篇文章主要給大家介紹了關(guān)于springboot后端接收前端傳數(shù)組參數(shù)三種方法,文中通過實例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2023-07-07Java如何接收前端easyui?datagrid傳遞的數(shù)組參數(shù)
這篇文章分享一下怎么在easyui的datagrid刷新表格時,在后端java代碼中接收datagrid傳遞的數(shù)組參數(shù),本文通過實例代碼給大家介紹的非常詳細,需要的朋友參考下吧2023-11-11一文帶你學(xué)習(xí)Java多維數(shù)組的使用技巧
Java作為一門廣泛應(yīng)用于各行各業(yè)的開發(fā)語言,具有豐富的數(shù)據(jù)類型支持,其中多維數(shù)組是其重要的一種,多維數(shù)組可以更加方便地組織數(shù)據(jù),提高Java應(yīng)用程序的效率,本文將為大家介紹Java中多維數(shù)組的基本概念和常用操作,助力讀者更好地掌握多維數(shù)組的使用技巧2023-11-11SpringBoot使用JTA實現(xiàn)對多數(shù)據(jù)源的事務(wù)管理
了解事務(wù)的都知道,在我們?nèi)粘i_發(fā)中單單靠事務(wù)管理就可以解決絕大多數(shù)問題了,但是為啥還要提出JTA這個玩意呢,到底JTA是什么呢?他又是具體來解決啥問題的呢?本文小編就給大家介紹一下如何在Spring Boot中使用JTA實現(xiàn)對多數(shù)據(jù)源的事務(wù)管理2023-11-11Java kafka如何實現(xiàn)自定義分區(qū)類和攔截器
這篇文章主要介紹了Java kafka如何實現(xiàn)自定義分區(qū)類和攔截器,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06