struct fileinfo{
char *fullpath;
int filesize;
int filemode;
struct disnode *tnode;
};
struct disnode{
int number;
struct {
int node;
int stat;
}s[number];
};
java中沒有結構體的概念,對於結構體你可以建立一個class與其對應,但是轉化過程必須自己寫。
例如你的結構體爲fileinfo,那麼你就可以建立一個FileInfo類對應他,但是在C中必須自己轉化,也就是傳入一個FileInfo的對象,然後對FileInfo對象的屬性通過fileinfo結構體逐一複製。
又或者你不建立class與其對應,多建立幾個String類型來接受結構體中的各個信息也可以。
但是java是不支持char *這種形式的字符串的,所以你必須把C中字符串表示方式轉換成java的String,java中String類型在c中表示形式其實就是jstring類型,它本身是一個複雜類型(jobject類型),實際爲執行內存的指針。
對於如何把char*轉變成jstring,你可以查看jni相關文檔,jni有很多內置函數實現這些功能。
對於複雜類型的轉換,如結構體轉換成jobject,需要自己手動轉換。java不直接支持結構體特性,因爲java的jni不是僅僅去支持C的。
////////////////
//通過GetObjectClass方法得到這個對象
jclass objectClass = (env)->GetObjectClass(obj);
//通過GetFieldID方法得到這個對象的fsize屬性
jfieldID fs = (env)->GetFieldID(objectClass,"filesize","I");
//再通過SetIntField()方法把這個屬性和結構體一一對應賦值對嗎?類似於下面這樣:
(env)->SetIntField(obj,fs,40);
不過有個地方不知道具體怎麼做:
如果這個FileInfo對象的有個屬性是一個數組的話,通過GetFieldID()這個JNI函數怎麼取得這個數組?
又怎麼把這個數組和結構體內的數組對應起來呢?
////////
JNI裏面也有專門處理數組的函數,其實如果你足夠了解java的話也應該知道數組也是一個object,其簽名爲[xtype的形式,其中x爲[的數量,type爲數組類型,例如[[i相當於int[][],[[Ljava/util/Date相當於Date[][]。所以數組本身也可以用GetObjectClass來獲得,但是處理數組元素需要專門的jni內置函數來處理。
最後提醒你一句,一定要記得回收內存噢。jni的字符串與數組最容易出現內存泄漏。
例如:FileInfo類有個屬性是 int ss[5]:
public class FileInfo{
public int filesize;
public int ss[] = new int[5];
}
在JNI的封裝中:
jclass objectClass = (env)->GetObjectClass(obj); //obj就是FileInfo類的實際對象
jfieldID fs = (env)->GetFieldID(objectClass,"filesize","I"); //可以獲取到int型的filesize這個屬性了
jfieldID ss = (env)->GetFieldID(objectClass,"ss","[I"); //這樣是不是可以獲取到int型的數組ss了?
如果可以的話,怎麼對這個ID ss進行實際的訪問操作?
jint jfs=(*env)->GetObjectField(env,cl,fs); //通過ID取得具體的數組
///////////
jfieldID
fs = (env)->GetFieldID(objectClass,"filesize","I");
這樣只是獲得對象字段的句柄指針,並沒有獲得字段的值,要獲得字段的值還需要其它操作,例如:
jint jfs=(*env)->GetObjectField(env,cl,fs);
如果獲得的是jstring類型或者是數組類型還需要進行轉換,轉換成char[]類型或者char*類型,例如
char* str=(*env)->GetStringUTFChars(env,jstr,NULL);
如果是基本數據類型數組的話,訪問其內部元素用GetXxxArrayElements(env,jarray,0);函數Xxx是類型名稱,返回Xxx*類型,
如int * i=GetIntArrayElements(env,jint,0)
如果是對象型數組就是jobject jobj=GetObjectArrayElement(env,jobjectArray,jsize),jobject是數組變量,jsize是偏移量,返回值是數組中對應偏移量的值。
舉例,java用一個類作爲參數傳遞給C++的函數,C++內部聲明瞭一個結構體來對應這個類的屬性
類中有個屬性是個int型的數組:int info[30]
在JNI封裝函數中這樣寫:
//取得類對象
jclass objectClass = (env)->GetObjectClass(sobj); //sobj即傳遞進來的類的對象
//取得該數組屬性的ID
jfieldID jarr_info = (env)->GetFieldID(objectClass,"info","[I"); //參數“[I”表示這個是int型數組
//通過ID取得具體的數組
jintArray jintarr = (jintArray)(env)->GetObjectField(sobj,jarr_info); //參數sobj是該封裝函數自動參數(JNIEnv *env, jclass sobj)中的jclass
//以上部分執行沒有問題,問題出在下面語句:
//要對數組進行操作,要取得該數組的數組指針,通過JNI的函數GetIntArrayElements()來取得:
jint *pia = (env)->GetIntArrayElements(jintarr,0);
class中有個屬性爲String類型:
public class FileInfo{
public String name;
}
JNI中:
//取得類對象
jclass objectClass = (env)->GetObjectClass(sobj); //sobj即傳遞進來的類的對象:new FileInfo()
//取得該String屬性的ID
jfieldID jname = (env)->GetFieldID(objectClass,"name","Ljava/lang/String;"); //參數“Ljava/lang/String;”表示這個是String型
//取得該屬性的具體值:
jstring js = (jstring)(env)->GetObjectField(sobj,jname);