4.1 Accessing Fields 域
域有两种:实例域和类域.
4.1.1 Procedure for Accessing an Instance Field 实例域
实例域:每个类的实例有各自的变量.
java层:
class Test{
private String s_test;
}
jni层:
jfieldID fid = (*env)->GetFieldID(env, cls, "s_test", "Ljava/lang/String;");
jstring jstr = (*env)->GetObjectField(env, obj, fid);
4.1.3 Accessing Static Fields 类域
类域:每个类的实例有相同的变量,因为对于类来说,static唯一.
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");
}
}
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);
}
实例域和类域的区别:
(1)调用函数不同:
GetStaticFieldID and GetFieldID
SetStaticIntField and SetIntField
(2)类域对应的是Static函数,对于类来说static变量唯一。
4.2
Calling Methods
class InstanceMethodCall {
private native void nativeMethod();
private void callback() {
System.out.println("In Java");
}
public static void main(String args[]) {
InstanceMethodCall c = new InstanceMethodCall();
c.nativeMethod();
}
static {
System.loadLibrary("InstanceMethodCall");
}
}
JNIEXPORT void JNICALL Java_InstanceMethodCall_nativeMethod(JNIEnv *env, jobject obj)
{
jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "()V");
if (mid == NULL) {
return; /* method not found */
}
printf("In C\n");
(*env)->CallVoidMethod(env, obj, mid);
}
4.2.2 Forming the Method Descriptor
Do not let C function prototypes such as “int f(void)” mislead you to thinking that "(V)I" is a valid method descriptor. Use "()I" instead.
4.2.3 Calling Static Methods
static方法和local方法的不同点:
static方法形参是cls,local方法的形参是obj.
class StaticMethodCall {
private native void nativeMethod();
private static void callback() {
System.out.println("In Java");
}
public static void main(String args[]) {
StaticMethodCall c = new StaticMethodCall();
c.nativeMethod();
}
static {
System.loadLibrary("StaticMethodCall");
}
}
JNIEXPORT void JNICALL Java_StaticMethodCall_nativeMethod(JNIEnv *env, jobject obj)
{
jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID mid = (*env)->GetStaticMethodID(env, cls, "callback", "()V");
if (mid == NULL) {
return; /* method not found */
}
printf("In C\n");
(*env)->CallStaticVoidMethod(env, cls, mid);
}
4.3 Invoking Constructors
构造函数"<init>"
jstring MyNewString(JNIEnv *env, jchar *chars, jint len)
{
jclass stringClass;
jmethodID cid;
jcharArray elemArr;
jstring result;
stringClass = (*env)->FindClass(env, "java/lang/String");
if (stringClass == NULL) {
return NULL; /* exception thrown */
}
/* Get the method ID for the String(char[]) constructor */
cid = (*env)->GetMethodID(env, stringClass,"<init>", "([C)V");
if (cid == NULL) {
return NULL; /* exception thrown */
}
/* Create a char[] that holds the string characters */
elemArr = (*env)->NewCharArray(env, len);
if (elemArr == NULL) {
return NULL; /* exception thrown */
}
(*env)->SetCharArrayRegion(env, elemArr, 0, len, chars);
/* Construct a java.lang.String object */
result = (*env)->NewObject(env, stringClass, cid, elemArr);
/* Free local references */
(*env)->DeleteLocalRef(env, elemArr);
(*env)->DeleteLocalRef(env, stringClass);
return result;
}