main
cネイティブコードで関数を呼び出すスレッドがあります。
これはJavaに戻らないので、メモリの割り当てに注意する必要があります。
main関数は、コールバックの方法としてJavaの静的メソッドを呼び出します。これがcでどのように達成されるかです:
void writeat(int x, int y, int style, char *string) {
JNIEnv *env = getJNIEnv();
static jmethodID cls_mid = NULL;
if (cls_mid == NULL) {
jclass clazz = (*env)->FindClass(env, "com/comp/prod/Kernel");
cls_mid = (*env)->GetStaticMethodID(env, clazz, "writeat",
"(IIILjava/lang/String;)V");
}
{
jstring out = (*env)->NewStringUTF(env, string);
(*env)->CallStaticVoidMethod(env, nullVoid, cls_mid, x, y, style,
out);
(*env)->DeleteLocalRef(env, out);
}
}
これはしばらくの間機能し、その後logcatに記録されたエラーなしで終了します。
CallStaticVoidMethod
通話をコメントアウトしても、同じことをします。new呼び出しとdelete呼び出しをコメントアウトしても、問題はありません。
これは、文字列「000」だけで1秒間に何百回も呼び出されるため、すぐにメモリが不足すると思います。
この時点ではログ猫に何も表示されないので、エラーの診断に関する情報を取得するためのヘルプは素晴らしいでしょう。
更新:私の古いメインとgetJNIEnv
JNIEnv *_env;
JNIEXPORT void JNICALL Java_com_comp_prod_main(JNIEnv *env,
jclass thiz) {
LOGV("Main called %d", __LINE__);
_env = (JNIEnv *) ((*env)->NewGlobalRef(env, env));
main();
_env = NULL;
}
JNIEnv *getJNIEnv(void) {
return _env;
}
私の新しいメインとgetJNIEnv
JavaVM *jvm;
JNIEXPORT void JNICALL Java_com_comp_prod_main(JNIEnv *env,
jclass thiz) {
LOGV("Main called %d", __LINE__);
//this is how to cache it for other threads
jint rs = (*env)->GetJavaVM(env, &jvm);
assert (rs == JNI_OK);
main();
jvm = NULL;
}
JNIEnv *getJNIEnv(void) {
JNIEnv *env;
jint rs = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
assert (rs == JNI_OK);
if(env == NULL)
{
LOGV("env is NULL");
}
return env;
}
Javaからの呼び出し:
Runnable runTerm = new Runnable() {
public void run() {
// call main()
Log.i(TAG, "About to call main on the c!");
try {
Terminal.main();
} catch (IOException e) {
e.printStackTrace();
}
}
};
t = new Thread(runTerm, "C thread");
t.start();