西西軟件下載最安全的下載網(wǎng)站、值得信賴(lài)的軟件下載站!

首頁(yè)編程開(kāi)發(fā)java → Java本地調(diào)用JNI使用規(guī)范詳解

Java本地調(diào)用JNI使用規(guī)范詳解

相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來(lái)源:西西整理時(shí)間:2012/10/31 11:50:05字體大。A-A+

作者:nuliniao點(diǎn)擊:0次評(píng)論:0次標(biāo)簽: 規(guī)范

  • 類(lèi)型:電子教程大小:3.2M語(yǔ)言:中文 評(píng)分:6.6
  • 標(biāo)簽:
立即下載

一、 JNI概述

JavaNative Interface的縮寫(xiě),中文為Java本地調(diào)用。從Java1.1開(kāi)始,JNI即成為Java標(biāo)準(zhǔn)的一部分。

JNI設(shè)計(jì)的目的是為了允許Java代碼與其他語(yǔ)言進(jìn)行交互。但這樣做通常會(huì)導(dǎo)致喪失平臺(tái)可移植性,通常是在特定的需求下進(jìn)行,例如使用舊的其他語(yǔ)言的庫(kù)、需要獲得Java類(lèi)庫(kù)不支持的某種基于具體平臺(tái)的特性、大量數(shù)學(xué)計(jì)算性能優(yōu)化等。

二、 JNI數(shù)據(jù)類(lèi)型和數(shù)據(jù)結(jié)構(gòu)

1.基本類(lèi)型

JNI基本類(lèi)型和本地等效類(lèi)型的對(duì)應(yīng)表格如下:

PSE: collapse" cellspacing="0">
Java類(lèi)型本地類(lèi)型說(shuō)明
booleanjboolean無(wú)符號(hào),8位
bytejbyte無(wú)符號(hào),8位
charjchar無(wú)符號(hào),16位
shortjshort有符號(hào),16位
intjint有符號(hào),32位
longjlong有符號(hào),64位
floatjfloat32位
doublejdouble64位
voidvoid無(wú)

為了使用方便,還提供了如下定義:

#define JNI_FALSE 0

#define JNI_TRUE 1

Jsize類(lèi)型用于描述主要指數(shù)和大小:

typedef jint jsize;

2.引用類(lèi)型

除了基本類(lèi)型外,JNI還包含了很對(duì)對(duì)應(yīng)于不同Java對(duì)象的引用類(lèi)型,JNI引用類(lèi)型的組織層次如下圖所示:


c語(yǔ)言中,所有其他JNI引用類(lèi)型都被定義為與jobject一樣,例如:

typedef jobject jclass;

在C++中,JNI引入虛構(gòu)類(lèi)以加強(qiáng)子類(lèi)關(guān)系,例如:

class _jobject{};

class _jstring : public jobject{};

typedef _jobject jobject;

typedef _jstring jstring;

3.方法ID和域ID

方法ID和域ID是常規(guī)的C指針類(lèi)型:

struct_jmethodID; /*不透明結(jié)構(gòu)*/

typedefstruct _jmethodID *jmethodID; /*方法ID*/

struct_jfieldID; /*不透明結(jié)構(gòu)*/

typedefstruct _jfieldID *jfieldID /*域ID*/

4.值類(lèi)型

jvalue聯(lián)合在參數(shù)數(shù)組中用作單元類(lèi)型,其聲明如下:

  typedefunion _jvalue
{
    jboolean z;
    jbyte b;
    jchar c;
    jshort s;
    jint i;
    jlong j;
    jfloat f;
    jdouble d;
    jobject l;
}jvalue;



5.UTF8字符串

JNI的UTF8字符串與標(biāo)準(zhǔn)UTF8格式有兩個(gè)區(qū)別,第一,空字節(jié)0使用雙字節(jié)格式進(jìn)行編碼,而不是標(biāo)準(zhǔn)UTF8的單字節(jié);第二,只使用單字節(jié)、雙字節(jié)和三字節(jié)格式,不支持更長(zhǎng)的字節(jié)格式。

三、 JNI接口函數(shù)命名方式

1. 類(lèi)型簽名

Java虛擬機(jī)的類(lèi)型簽名如下:

類(lèi)型簽名Java類(lèi)型
Zboolean
Bbyte
Cchar
Sshort
Iint
Jlong
Ffloat
Ddouble
Lfully-qulitied-class;全限定類(lèi)
[typetype[] 數(shù)組
(argtypes)rettype方法類(lèi)型

例如,Java方法int feet(int n, String s,int [] arr)的類(lèi)型簽名如下:

(ILJava/lang/String;[I)I

圓括號(hào)里面為參數(shù),I表示第一個(gè)參數(shù)int型,LJava/lang/String;表示第二個(gè)參數(shù)為全限定Java.lang.String類(lèi)型,[I表示第三個(gè)參數(shù)為int型的數(shù)組,圓括號(hào)后面為返回值類(lèi)型,I表示返回值為int型。

2. 一般函數(shù)的JNI接口函數(shù)命名方式

一般JNI接口函數(shù)命名如下:

Java_包名_類(lèi)名_方法名。

例如:某工程下Sample/test包下MySigal類(lèi)的int GetASample()方法的C語(yǔ)言實(shí)現(xiàn)函數(shù)命名如下:

jint Java_Sample_test_MySigal_GetASample(JNIEnv* env,jobjectobj)

其中,包名所包含的“/”應(yīng)全部以下劃線替代,其本地實(shí)現(xiàn)的參數(shù)和返回值也應(yīng)轉(zhuǎn)換為JNI類(lèi)型。

3. 重載函數(shù)的JNI接口函數(shù)命名方式

重載函數(shù)的JNI實(shí)現(xiàn)在一般函數(shù)的JNI實(shí)現(xiàn)之外,還應(yīng)添加上類(lèi)型簽名以作為同名函數(shù)之間的區(qū)別,其接口函數(shù)命名如下:

Java_包名_類(lèi)名_方法名_參數(shù)簽名。

例如:某工程下Sample/test包下MySigal類(lèi)的int GetASample(int n, String s,int [] arr)方法的C語(yǔ)言實(shí)現(xiàn)函數(shù)命名如下:

jintJava_Sample_test_MySigal_GetASample_ILJava_lang_String_2_3I

(JNIEnv*env, jobject obj, jint n, jstring s, jintarray arr)。

JNI在函數(shù)命名時(shí)采用名字?jǐn)_亂方案,以保證所有的Unicode字符都能轉(zhuǎn)換為有效的C函數(shù)名,所有的“/”,無(wú)論是包名中的還是全限定類(lèi)名中的,均使用“_”代替,用_0,…,_9來(lái)代替轉(zhuǎn)義字符,如下:

轉(zhuǎn)義字符序列表示
_0XXXXUnicode字符XXXX
_1字符“_”
_2簽名中的字符“;”
_3簽名中的字符“[”

四、 JNI函數(shù)與API

在目前的應(yīng)用中,我們所主要需要關(guān)心的是C/C++數(shù)據(jù)類(lèi)型與JNI本地類(lèi)型之間的轉(zhuǎn)化過(guò)程,這個(gè)過(guò)程某些數(shù)據(jù)的轉(zhuǎn)換需要使用JNIEnv對(duì)象的一系列方法來(lái)完成。

1.jstring轉(zhuǎn)換為C風(fēng)格字符串

char* test = (char*)(*env)->GetStringUTFChars(env,jstring,NULL);

使用完畢后,應(yīng)調(diào)用:

(*env)->ReleaseStringUTFChars(env,jstring, test);

釋放資源。

2.C風(fēng)格字符串轉(zhuǎn)換為jstring

char charStr[50];

jstring jstr;

jstr = env ->NewStringUTF(charStr);

3.C語(yǔ)言中獲取的一段char*的buffer傳遞給Java

在jni中new一個(gè)byte數(shù)組,然后使用

(*env)->SetByteArrayRegion(env,bytearray, 0, len, buffer)

操作將buffer拷貝到數(shù)組中。

這種方式主要是針對(duì)buffer中存在“\0”的情況,如果以C風(fēng)格字符串的方式讀入,就會(huì)損失“\0”之后的字符。

4.?dāng)?shù)組操作

數(shù)組操作的相關(guān)函數(shù)列表如下:

JNI函數(shù)功能
GetArrayLength返回?cái)?shù)組中的元素?cái)?shù)
NewObjectArray創(chuàng)建一個(gè)指定長(zhǎng)度的原始數(shù)據(jù)類(lèi)型數(shù)組
GetObjectArrayElement返回Object數(shù)組的元素
SetObjectArrayElement設(shè)置Object數(shù)組的元素
GetObjectArrayRegion將原始數(shù)據(jù)類(lèi)型數(shù)組中的內(nèi)容拷貝到預(yù)先分配好的內(nèi)存緩存中
SetObjectArrayRegion設(shè)置緩存中數(shù)組的值
ReleaseObjectArrayRegion釋放GetObjectArrayRegion分配的內(nèi)存

對(duì)int,char等基本數(shù)據(jù)類(lèi)型的數(shù)組操作,將相關(guān)Object名稱(chēng)替換為對(duì)應(yīng)基本數(shù)據(jù)類(lèi)型名稱(chēng)即為相關(guān)函數(shù)。

數(shù)組操作的方法選擇基于使用者的需求而定,如果使用者需要在內(nèi)存中拷貝數(shù)組并對(duì)其進(jìn)行操作那么一般使用GetObjectArrayRegion和SetObjectArrayRegion函數(shù),否則一般使用SetObjectArrayElement和GetObjectArrayElement函數(shù)。

    相關(guān)評(píng)論

    閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過(guò)難過(guò)
    • 5 囧
    • 3 圍觀圍觀
    • 2 無(wú)聊無(wú)聊

    熱門(mén)評(píng)論

    最新評(píng)論

    發(fā)表評(píng)論 查看所有評(píng)論(0)

    昵稱(chēng):
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過(guò)審核才能顯示)
    推薦文章

    沒(méi)有數(shù)據(jù)