美文网首页
JNI学习记录4-Fields

JNI学习记录4-Fields

作者: ai___believe | 来源:发表于2017-03-03 17:30 被阅读37次

JNI学习记录1-初建JNI工程
JNI学习记录2-local refence崩溃问题
JNI学习记录3-String and Array
JNI学习记录4-Fields
JNI学习记录5-Methods

一、Accessing Fields

  • Java语言支持两种成员(field):(static)静态成员和实例成员. 在JNI获取和赋值成员的方法是不同的.
  • Java层的field和method,不管它是public,还是package、private和protected,从JNI都可以访问到,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");
}
}

JNI:

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);
}

Procedure for Accessing an Instance Field

  1. jclass cls = (*env)->GetObjectClass(env, obj); //从对象获得类。
  2. fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;"); //获得fieldid
  3. jstr = (*env)->GetObjectField(env, obj, fid); //获得field

示例中要得到的是一个对象类型,所以用GetObjectField. 此外JNI还提供
Get/SetIntField,Get/SetFloatField访问不同类型成员。

二、Field Descriptors

descriptors.png

例如:
java方法:long f (int n, String s, int[] arr);<------->signature: "(ILjava/lang/String;[I)J"

  • 签名是一种用参数个数和类型区分同名方法的手段,即解决方法重载问题。
  • 类描述符开头的'L'与结尾的';'必须要有
  • 数组描述符,开头的'['必须有.
  • 方法描述符规则: "(各参数描述符)返回值描述符",其中参数描述符间没有任何分隔符号

三、Accessing Static Fields

Java:

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");
}
}

JNI:

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);
}

流程与实例成员类似。

相关文章

网友评论

      本文标题:JNI学习记录4-Fields

      本文链接:https://www.haomeiwen.com/subject/qbyrgttx.html