2016-10-03 78 views
1

我試圖建立一個本地方法,雖然它看起來運行良好,但我努力理解函數中的字段[* SIG] -澄清有關GetFieldID

jfieldID GetFieldID(JNIEnv *env, jclass clazz, 
    const char *name, const char *sig); 

https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html

例如,我有一個小型Java代碼,它使用一個名爲「i」的實例變量,所有這種本機方法(名爲test)所做的就是將其乘以2.

現在我指的是Java完全參考手冊 - 代碼就像 -

我的問題是 - 這是什麼「I」 - fid =(* env) - > GetFieldId(env,cls,「i」,「I」);

當我讀到甲骨文documenttion它說 - https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html

對象
的訪問字段GetFieldID

jfieldID GetFieldID(JNIEnv *env, jclass clazz,
const char *name, const char *sig); 

返回字段ID爲實例(非靜態)域一類。該字段由其名稱和簽名指定。 GetField和SetField系列訪問器函數使用字段ID來檢索對象字段。
GetFieldID()會導致未初始化的類被初始化。
GetFieldID()不能用於獲取數組的長度字段。應使用GetArrayLength()代替。
LINKAGE:
JNIEnv接口函數表中的索引94。
參數:
env:JNI接口指針。
clazz:一個Java類對象。
名稱:以0結尾的已修改UTF-8字符串中的字段名稱。
sig:以0結尾的已修改UTF-8字符串中的字段簽名。

請問您可能會詳細說明該字段「sig」是什麼?我無法將「我」與任何東西聯繫起來。

#include <jni.h> 
#include "NativeDemo.h" 
#include <stdio.h> 

JNIEXPORT void JNICALL Java_NativeDemo_test(JNIEnv *env , jobject obj) 
{ 
    jclass cls; 
    jfieldID fid; 
    jint i; 

    printf("Starting the native method\n"); 

    cls = (*env)->GetObjectClass(env,obj); 
    fid = (*env)->GetFieldId(env,cls,"i", "I"); 
+0

這種性質的JNI方法或字段簽名是該方法或字段的'javap -s'命令輸出的內容。當有一種工具可以幫助你時,不要試圖自己弄清楚。 – EJP

回答

1

請參見下面的Java核心,訴2通道的 「員工」 的例子。 12,由Horstmann和康奈爾在http://www.horstmann.com/corejava.html 「id」是該字段的名稱,這裏是 私人雙重工資; Employee類中的 ;其簽名(「sig」)或類型,「D」(雙)也必須指定。在你的代碼中,「I」是整數。 請參閱「類型字段」http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html 一旦獲得了jFieldId,它就可以用來修改 字段的值。

/** 
    @version 1.10 1999-11-13 
    @author Cay Horstmann 
*/ 

#include "Employee.h" 
#include <stdio.h> 

JNIEXPORT void JNICALL Java_Employee_raiseSalary(JNIEnv* env, jobject  this_obj, jdouble byPercent) 
{ 
    /* get the class */ 
    jclass class_Employee = (*env)->GetObjectClass(env, this_obj); 

    /* get the field ID */ 
    jfieldID id_salary = (*env)->GetFieldID(env, class_Employee, "salary", "D"); 

    /* get the field value */ 
    jdouble salary = (*env)->GetDoubleField(env, this_obj, id_salary); 

    salary *= 1 + byPercent/100; 

    /* set the field value */ 
    (*env)->SetDoubleField(env, this_obj, id_salary, salary); 
} 
+0

謝謝。這回答了我的問題。 –

2

這裏的「I」是原始整數類型的簽名。Oracle提供類型簽名的表格:http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html#wp276

  • ž布爾
  • 乙字節
  • c char字符
  • š短
  • I INT
  • Ĵ長
  • ˚F浮子
  • D雙

對於非原始類型,簽名是窗體的

  • 大號完全合格的類;

對於數組,[添加。

對於方法,()用於從返回值中分離參數。

+0

謝謝。這回答了我的問題。 –