多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
Java语言支持两种类型的属性,每一个对象都会有一份自己的实例属性,而所有实例都共享所属类的静态属性。 JNI提供了用于获取或者设置对象实例属性以及类静态属性的函数。让我们先看下以下示例代码,它展示了如何从一个原生函数视线中访问对象的实例属性。 ~~~ class InstanceFieldAccess { static { System.loadLibrary("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 + "\""); } } ~~~ 类InstanceFieldAccess类定义了一个类属性.main函数创建一个对象实例,设置了实例属性然后调用原生方法InstanceFieldAccess.accessField.正如你看到的那样,这个原生方法打印出实例中属性s的值,然后将它设置为一个新的值。在原生方法返回之后程序在此打印了该属性的值,用于展示这个属性是确实被修改了。 ~~~ #include <jni.h> #ifdef __cplusplus extern "C" { #endif /* * Class: InstanceFieldAccess * Method: accessField * Signature: ()V */ 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) { 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) { 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) { return; /*out of memory */ } (*env)->SetObjectField(env, obj, fid, jstr); } #ifdef __cplusplus } #endif ~~~ 运行以上的InstanceFieldAccessClass,你将会得到以下输出。 ~~~ In C: c.s = "abc" In Java: c.s = "123" ~~~