Jni開發代碼簡介

JNI中方法參數:

jstring Java_com_utils_INative_stringFromJNI(JNIEnv* env,

jobject thiz, jstring obj) {
return (*env)->NewStringUTF(env, "XXX");

}

此方法中有三個參數:

第一個env是結構體的函數表-->JavaNativeInterface的接口。

第二個參數thiz區別當前方法爲靜太方法或者實例方法,當方法是一個實例方法時,則此參數相當於對象本身,即類似this關鍵字; 當方法爲一個靜態方法時,thiz將指向所在的類。

第三個參數obj則是由java定義時傳過來的參數,類型可多種類型。


在JNI中數據類型對應時,C/C++的類型格式是:在java的數據類型前加上"j"。如:int --->jint 

而Java中的“String” 則需要通過env->NewStringUTF(env, "");來得到“jstring"對應其類型,除此之外,在jni中還定義了'jclass'對應java中的"Class"類、“jobject”對應java中的“Object”。


字符串轉換:

   char * c ;

   c = env->GetStringUTFChars(env, obj, null);//可返回char

   env->RealeseStringUTFChars(env, obj, c);//銷燬GetStringUTFChars時分配的內存

   jstring str  = env->NewStringUTF(env, c);


獲取Java類的成員並修改:

Java:

class InstanceFieldAccess {
     private String s;
     private native void accessField();
     public static void main(String args[]) {
     InstanceFieldAccess c = new InstanceFieldAccess();
     c.s = "abc";
     c.accessField();
     System.out.println("In Java:");
     System.out.println(" c.s = \"" + c.s + "\"");
     }
    static {
          System.loadLibrary("InstanceFieldAccess");
    }
}

C:

JNIEXPORT void JNICALLJava_InstanceFieldAccess_accessField(JNIEnv *env, jobject obj){ 
     jfieldID fid; /* store the field ID */  
     jstring jstr;  
     const char *str;  /* Get a reference to obj’s class */
     jclass cls = (*env)->GetObjectClass(env, obj);  

     fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;");  
     printf("In C:\n");
     if (fid == NULL) {    
          return; /* failed to find the field */ 
     }    
     jstr = (*env)->GetObjectField(env, obj, fid);  
     str = (*env)->GetStringUTFChars(env, jstr, NULL);  
     if (str == NULL) {    
          return; /* out of memory */
     }  
     printf(" c.s = \"%s\"\n", str);
     (*env)->ReleaseStringUTFChars(env, jstr, str);  /* Create a new string and overwrite the instance field */  
     jstr = (*env)->NewStringUTF(env, "123");  
     if (jstr == NULL) {    
          return; /* out of memory */ 
     }  
     (*env)->SetObjectField(env, obj, fid, jstr);
}

輸出:

     In C:     c.s = "abc"     In Java:     c.s = "123"


訪問對象成員分兩步,首先通過 GetFieldID 得到對象成員 ID, 如下:fid =(*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;");
示例代碼,通過 GetObjectClass 從 obj 對象得到 cls.這時,通過在對象上調用下述方法獲得成員的值:jstr =(*env)->GetObjectField(env, obj, fid);
示例中要得到的是一個對象類型,所以用 GetObjectField. 此外 JNI 還提供Get/SetIntField,Get/SetFloatField 訪問不同類型成員。
譯者:通過 JNI 方法訪問對象的成員,JNI 對應的函數命名非常有規律,即 Get/Set<ReturnValue Type>Field。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章