JNI入門實踐

JNI 全稱 Java Native Interface义矛。Java本地方法接口份氧,它是Java語言允許Java代碼與C存崖、C++代碼交互的標(biāo)準機制静暂。維基百科是這樣解釋的:“當(dāng)應(yīng)用無法完全用Java編程語言實現(xiàn)的時候,(例如晦毙,標(biāo)準Java類庫不支持的特定平臺特性或者程序庫時)生巡,JNI使得編程者能夠編寫native方法來處理這種情況”。這就意味著见妒,在一個Java應(yīng)用程序中孤荣,我們可以使用我們需要的C++類庫,并且直接與Java代碼交互须揣,而且在可以被調(diào)用的C++程序內(nèi)垃环,反過來調(diào)用Java方法(回調(diào)函數(shù))。

JNI的優(yōu)勢

  • 操作系統(tǒng)相關(guān) JNI使得一些"過程"無需在Java中實現(xiàn)返敬。例如,硬件敏感的寥院,或者直接與操作系統(tǒng)API關(guān)聯(lián)的命令劲赠。
  • 性能優(yōu)化 底層的庫,如圖形秸谢,計算凛澎,各種類型的渲染等等,可以提高應(yīng)用的運行性能估蹄。
  • 既有實現(xiàn) 已經(jīng)有大量的庫已經(jīng)被實現(xiàn)塑煎,編程者可直接使用,不用再自行編寫臭蚁。這里的庫指的是用其他編程語言實現(xiàn)的程序庫最铁,例如IO流或者線程等底層與OS交互的操作都是由C/C++實現(xiàn)的讯赏。

JNI的實現(xiàn)

1、定義Java類

定義一個帶native方法的java類如:

/**
 * @author jack
 */
public class JniCompileTest {
    /**
     * 執(zhí)行jni調(diào)用
     */
    public native Map<String, String> excute(String param1, Object param2);
}
2冷尉、生成頭文件

在項目的根目錄下執(zhí)行javah命令

javah -classpath . -jni com.package.jni.test.JniCompileTest

完成后漱挎,會在根目錄下生成一個同名的.h結(jié)尾的頭文件。

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

#ifndef _Included_com_package_jni_test_JniCompileTest
#define _Included_com_package_jni_test_JniCompileTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_package_jni_test_JniCompileTest
 * Method:    excute
 * Signature: (Ljava/lang/String;Ljava/lang/Object;)Ljava/util/Map;
 */
JNIEXPORT jobject JNICALL Java_com_package_jni_test_JniCompileTest_excute
  (JNIEnv *, jobject, jstring, jobject);
#ifdef __cplusplus
}
#endif
#endif
3雀哨、引入頭文件

在頭文件中的 jni.h 如果在編譯動態(tài)鏈接庫(.so文件)的時候找不到磕谅,可以去本地的JDK目錄中的include文件下找到兩個文件:jni.hjni_md.h 。然后拷貝到與JniCompileTest.h同目錄下雾棺。

修改引入方式

#include <jni.h> 

改為

#include "jni.h" 

然后可以定義一個同名的cpp源碼文件膊夹,開發(fā)JNI的cpp實現(xiàn)了

//
// Created by jack on 2021/7/10.
//
#include "com_package_jni_test_JniCompileTest.h"

JNIEXPORT jobject JNICALL Java_com_package_jni_test_JniCompileTest_excute
        (JNIEnv *env, jobject, jstring, jobject){
    // do something
    return NULL;
}
4、編譯動態(tài)鏈接庫

在clion中構(gòu)建一個cmake項目捌浩,然后寫CMakeLists.txt

project(JniCompileTest C CXX)
cmake_minimum_required(VERSION 2.8.0)
# 這里用自己的目錄即可
INCLUDE_DIRECTORIES(src/main/cpp/jnilib/include/)

FILE(GLOB SRC_JNI_LIBRARY src/main/cpp/jnilib/src/*.cpp)
FILE(GLOB HEADER_JNI_LIBRARY src/main/cpp/jnilib/include/*.h)

add_library(JniCompileTest SHARED ${HEADER_JNI_LIBRARY} ${LIST_SRC} ${SRC_JNI_LIBRARY})

完成后執(zhí)行編譯

5放刨、java引入動態(tài)鏈接庫

java 使用動態(tài)庫,需要用System類load嘉栓,例如在上面的類的構(gòu)造方法的中加入即可宏榕。

/**
 * @author jack
 */
public class JniCompileTest {
    public JniCompileTest(){
        // mac下文件為JniCompileTest.dylib
        File outputJNIFile = new File("/user/jack/JniCompileTest.so");
        System.load(outputJNIFile.getAbsolutePath());
    }
    /**
     * 執(zhí)行jni調(diào)用
     */
    public native Map<String, String> excute(String param1, Object param2);
}

結(jié)尾

JNI的封裝完成,但是在JNI的開發(fā)中侵佃,還是不少注意的地方麻昼,例如JNI對象的定義,如何解析java傳遞來的對象馋辈,如果回調(diào)java方法等抚芦。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市迈螟,隨后出現(xiàn)的幾起案子叉抡,更是在濱河造成了極大的恐慌,老刑警劉巖答毫,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件褥民,死亡現(xiàn)場離奇詭異,居然都是意外死亡洗搂,警方通過查閱死者的電腦和手機消返,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來耘拇,“玉大人撵颊,你說我怎么就攤上這事”古眩” “怎么了倡勇?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嘉涌。 經(jīng)常有香客問我妻熊,道長夸浅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任固耘,我火速辦了婚禮题篷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘厅目。我一直安慰自己番枚,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布损敷。 她就那樣靜靜地躺著肄扎,像睡著了一般无牵。 火紅的嫁衣襯著肌膚如雪篡诽。 梳的紋絲不亂的頭發(fā)上罕模,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音诱桂,去河邊找鬼洋丐。 笑死,一個胖子當(dāng)著我的面吹牛挥等,可吹牛的內(nèi)容都是我干的友绝。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼肝劲,長吁一口氣:“原來是場噩夢啊……” “哼迁客!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辞槐,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤掷漱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后榄檬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卜范,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年鹿榜,在試婚紗的時候發(fā)現(xiàn)自己被綠了先朦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡犬缨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出棉浸,到底是詐尸還是另有隱情怀薛,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布迷郑,位于F島的核電站枝恋,受9級特大地震影響创倔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜焚碌,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一畦攘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧十电,春花似錦知押、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至畏线,卻和暖如春静盅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寝殴。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工蒿叠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蚣常。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓市咽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親史隆。 傳聞我的和親對象是個殘疾皇子魂务,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容