class Callback {
static {
System.loadLibrary("callback");
}
public native void nativeMethod(int depth);
// Native Method からコールされるメソッド
public void callback(int depth) {
String h = "";
if (depth < 5) {
for (int i=0; i<depth; i++) h += " ";
System.out.println(h+"Java : Depth="+depth);
// 再度 Native Method をコールする
nativeMethod(depth+1);
System.out.println(h+"Java : Depth="+depth);
} else {
System.out.println(h+"LIMIT");
}
}
public static void main(String args[]) {
Callback c = new Callback();
c.callback(0);
}
}
|
Native Method からコールされるメソッドとして、callback() を用意した。この中でまた Native Method をコールして、深さが 5 になるまで繰り返す。
#include <jni.h>
#include "Callback.h"
#include <stdio.h>
void indent(int level) {
int i;
for (i=0; i<level; i++) printf(" ");
}
JNIEXPORT void JNICALL
Java_Callback_nativeMethod(JNIEnv *env, jobject obj, jint depth) {
jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "(I)V");
if (mid == 0) return;
indent(depth);
printf("C : Depth=%d\n", depth); fflush(stdout);
/* Java のメソッドをコール */
(*env)->CallVoidMethod(env, obj, mid, depth);
indent(depth);
printf("C : Depth=%d\n", depth); fflush(stdout);
}
|
まず Native Method は、GetObjectClass() により、自分のクラスの Class オブジェクトを取得する。 その Class オブジェクトを使ってメソッドを取得するには、次の GetMethodID() を使う。 この引数にメソッド名 ("callback") と引数・返値 ("(I)V") を渡すと、そのメソッドへの参照が得られる。 もしメソッドが見つからなかった場合、GetMethodID() は 0 を返す。 そして、最後に CallVoidMethod() で Java のメソッドをコールする。
% java Callback
Java : Depth=0
C : Depth=1
Java : Depth=1
C : Depth=2
Java : Depth=2
C : Depth=3
Java : Depth=3
C : Depth=4
Java : Depth=4
C : Depth=5
LIMIT
C : Depth=5
Java : Depth=4
C : Depth=4
Java : Depth=3
C : Depth=3
Java : Depth=2
C : Depth=2
Java : Depth=1
C : Depth=1
Java : Depth=0