JNIシリーズ(4):カスタムクラスオブジェクトへのアクセス方法

1758 ワード

JNI仕様ではString,Arrayの2つの参照タイプのアクセスのみが与えられていますが、カスタムクラスを使用している場合、JNIではどのようにアクセスしますか?次のコードに示すように、ユーザーはStudioクラスをカスタマイズし、インスタンスstudentを作成し、JNI関数でインスタンスstudentのメンバーageを変更します.
package com.demo;



public class Demo {

	Student student = new Student("Jim", 15);



	public static void main(String[] args) {

		Demo d = new Demo();

		System.out.println("Before setting: " + student.toString());

		d.setStudentAge(student);

		System.out.println("After setting: " + student.toString());

	}



	native void setStudentAge(Student student);



	static {

		// Loading the dynamic link library

	}

}



class Student {

	String name;

	int age;



	public Student(String name, int age) {

		this.name = name;

		this.age = age;

	}



	public void toString() {

		return name + ":" + age;

	}

}

対応するJNI関数:
Java_com_demo_Demo_setStudentAge(JNIEnv* env, jobject obj, jobject student)

{

	// How to access 'age' member of student ?

}

実は考え方は同じで、まずStudentクラスを見つけて、それから‘age’のfieldIDを見つけます.
struct fieldIds {

	jclass studentClass;

	jfieldID name;

	jfieldID age;

}studentFieldIds;



Java_com_demo_Demo_setStudentAge(JNIEnv* env, jobject obj, jobject student)

{

	studentFieldIds.studentClass = (*env)->FindClass(env, "com/demo/Student");

	if (studentClass == NULL)

		return;



	studentFieldIds.name = (*env)->GetFieldID(env, studentFieldIds.studentClass, "name", "Ljava/lang/String;");

	studentFieldIds.age = (*env)->GetFieldID(env, studentFieldIds.studentClass, "age", "I");



	// change the 'age' value of student

	(*env)->SetIntField(env, student, studentFieldIds.age, 20);

}