JAVA-JNI中jfieldID

来源:互联网 发布:网络命令大全 编辑:程序博客网 时间:2024/06/03 12:43

访问JAVA中的字段(jfieldID)

JAVA 支持两种 field(字段),每一个对象的实例都有一个对象字段的复制;所有的对象共享一个类的静态字段。

访问对象字段
先看一个从本地代码中访问对象字段的例子: 

复制代码
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");      }  } 
复制代码

下面是本地方法的实现:

复制代码
JNIEXPORT void JNICALL  Java_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); //第一步     printf("In C:\n");        /* Look for the instance field s in cls */      fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;"); //第二步     if (fid == NULL) {          return; /* failed to find the field */      }           /* Read the instance field s */      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 获取 field ID(字段ID)、字段名字和字段描述符: 
Fid=(*env)->GetFieldID(env,cls,”s”,”Ljava/lang/String;”); 
上例中的代码通过在对象引用obj上调用GetObjectClass获取到类引用。一旦获取到字段ID,
你就可以把对象和字段 ID作为参数来访问字段: 
Jstr=(*env)->GetObjectField(env,obj,fid); 
因为字符串和数组是特殊的对象,所以我们使用GetObjectField 来访问字符串类型的实例字段。
除了 Get/SetObjectField,JNI 还支持其它如 GetIntField、SetFloatField 等用来访问基本类型字段的函数。 


Ljava/lang/String这个字符串被称为JNI field descriptor(字段描述符)。
字符串的内容由字段被声明的类型决定

 

 

访问静态字段
访问静态字段和访问实例字段相似,看下面这个InstanceFieldAccess 例子的变形:

复制代码
class StaticFielcdAccess {      private static int si;        private native void accessField();      public static void main(String args[]) {          StaticFieldAccess c = new StaticFieldAccess();          StaticFieldAccess.si = 100;          c.accessField();          System.out.println("In Java:");          System.out.println("  StaticFieldAccess.si = " + si);      }      static {          System.loadLibrary("StaticFieldAccess");      } } 
复制代码

下面是本地方法StaticFieldAccess.accessField 的实现:

复制代码
JNIEXPORT void JNICALL  Java_StaticFieldAccess_accessField(JNIEnv *env, jobject obj)  {      jfieldID fid;   /* store the field ID */      jint si;        /* Get a reference to obj's class */      jclass cls = (*env)->GetObjectClass(env, obj);        printf("In C:\n");        /* Look for the static field si in cls */      fid = (*env)->GetStaticFieldID(env, cls, "si", "I");      if (fid == NULL) {          return; /* field not found */      }      /* Access the static field si */      si = (*env)->GetStaticIntField(env, cls, fid);      printf("  StaticFieldAccess.si = %d\n", si);      (*env)->SetStaticIntField(env, cls, fid, 200);  } 
复制代码

运行程序可得到输出结果: 
In C: 
   StaticFieldAccess.si = 100 
 In Java: 
   StaticFieldAccess.si = 200

0 0
原创粉丝点击