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
- jclass cls = (*env)->GetObjectClass(env, obj); //从对象获得类。
- fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;"); //获得fieldid
- jstr = (*env)->GetObjectField(env, obj, fid); //获得field
示例中要得到的是一个对象类型,所以用GetObjectField. 此外JNI还提供
Get/SetIntField,Get/SetFloatField访问不同类型成员。
二、Field Descriptors
![](https://img.haomeiwen.com/i2305000/b21c5497bb34e884.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);
}
流程与实例成员类似。
网友评论