本文是JNI系列的第二篇,介紹JNI中的基本數據類型,以及Java和native的傳遞約定。
系列文章的大綱如下:
JNI中的基本數據類型JNI中的基本類型也稱為Native基本類型。
在Java中的基本類型與JNI中的基本類型的對應關係如下:
Java類型Native類型說明booleanjbooleanunsigned 8 bitsbytejbytesigned 8 bitscharjcharunsigned 16 bitsshortjshortsigned 16 bitsintjintsigned 32 bitslongjlongsigned 64 bitsfloatjfloat32 bitsdoublejdouble64 bitsvoidvoidN/A在Native中定義了jboolean的兩個取值:
#define JNI_FALSE 0
#define JNI_TRUE 1
同時還定義jsize類型用於處理索引以及大小:
typedef jint jsize;
以上就是native中的基本類型,以及與Java中基本類型的對應關係,下面就一起來看看如何在Java與native中進行傳遞吧!
傳遞基本類型參數在JNI簡介中完整的介紹了如果在Java中調用native中的函數。但是並沒有傳遞參數。在Java與native間傳遞基本數據類型是十分簡單而又直接的,在Java的native方法的參數和返回值,在生成的頭文件的函數籤名中使用上一節介紹的對應的native類型進行替換,在C/C++的實現中直接使用即可。
實例我們來看一個實例。
Hello.java
package myjni;
public class Hello {
static {
System.loadLibrary("hello");
}
public native short addShort(short a, short b);
public static void main(String[] args) {
Hello hello = new Hello();
short a = 1;
short b = 2;
System.out.println("addShort(" + a + ", " + b + ") = " + hello.addShort(a, b));
}
}
如果還不清楚如果生成頭文件請參考JNI簡介和使用IntelliJ IDEA和CLion開發JNI環境搭建。
生成頭文件myjni_Hello.h的籤名為:
/*
* Class: myjni_Hello
* Method: addShort
* Signature: (SS)S
*/
JNIEXPORT jshort JNICALL Java_myjni_Hello_addShort
(JNIEnv *, jobject, jshort, jshort);
實現函數Java_myjni_Hello_addShort:
JNIEXPORT jshort JNICALL Java_myjni_Hello_addShort(JNIEnv *env, jobject obj, jshort ja, jshort jb) {
jshort ret = ja + jb;
return ret;
}
編譯生成動態庫,並運行Java程序得到輸出:
addShort(1, 2) = 3
傳遞其他數據類型也是一樣的操作。注意如果返回true或者false,在native代碼中直接使用JNI_FALSE或者JNI_TRUE。
類型籤名在生成的頭文件中,函數會有如下的注釋:
/*
* Class: myjni_Hello
* Method: addShort
* Signature: (SS)S
*/
Class和Method的值很容易理解,Signature的值(SS)S是什麼含義呢?
這其實是JVM中的類型的表示方法,有如下對應關係:
類型籤名Java類型ZbooleanBbyteCcharSshortIintJlongffloatDdoubleVvoidLfully-qualified-class;fully-qualified-class[typetype[](arg-types)ret-typemethod type上表中單個大寫字母很好理解,其中的V用於函數返回值。
對於fully-qualified-class,看例子來理解,Java中的String類型的類型籤名為Ljava/lang/String;,開頭為L,結尾是;。
對於Java中的數組,如int[],類型籤名為[I。
最後一個表示方法的籤名,如(SS)S,表示函數參數是兩個short類型,返回值是short。
括號內SS是函數的參數類型,括號外的S是函數的返回值類型。
如Java中的方法:
long f (int n, String s, int[] arr);
類型籤名為:
(ILjava/lang/String;[I)J
本文完。