+ mmodule.ensure_linking_callback_methods(ffi_ccu)
+
+ # Function to build instances to the Java class NitObject
+ var callbacks = mmodule.callbacks_used_from_java.callbacks
+ if callbacks.not_empty then
+ var cf = new CFunction("jobject nit_ffi_with_java_new_nit_object(JNIEnv *env, void *data)")
+ cf.exprs.add """
+ // retrieve the current JVM
+ Sys sys = Pointer_sys(NULL);
+
+ jclass java_class = Sys_load_jclass(sys, "nit/app/NitObject");
+ if (java_class == NULL) {
+ PRINT_ERROR("Nit FFI with Java error: failed to load class NitObject.\\n");
+ (*env)->ExceptionDescribe(env);
+ exit(1);
+ }
+
+ jmethodID java_init = (*env)->GetMethodID(env, java_class, "<init>", "(J)V");
+ if (java_init == NULL) {
+ PRINT_ERROR("Nit FFI with Java error: NitObject constructor not found.\\n");
+ (*env)->ExceptionDescribe(env);
+ exit(1);
+ }
+
+ jobject nit_object = (*env)->NewObject(env, java_class, java_init, (jlong)data);
+ if (nit_object == NULL) {
+ PRINT_ERROR("Nit FFI with Java error: NitObject construction failed.\\n");
+ (*env)->ExceptionDescribe(env);
+ exit(1);
+ }
+
+ return nit_object;
+ """
+ ffi_ccu.add_local_function cf
+
+ # Function to extract the pointer held by instances of the Java class NitObject
+ cf = new CFunction("void *nit_ffi_with_java_nit_object_data(JNIEnv *env, jobject nit_object)")
+ cf.exprs.add """
+ Sys sys = Pointer_sys(NULL);
+ jclass java_class = Sys_load_jclass(sys, "nit/app/NitObject");
+ if (java_class == NULL) {
+ PRINT_ERROR("Nit FFI with Java error: failed to load class NitObject.\\n");
+ (*env)->ExceptionDescribe(env);
+ exit(1);
+ }
+
+ jfieldID java_field = (*env)->GetFieldID(env, java_class, "pointer", "J");
+ if (java_field == NULL) {
+ PRINT_ERROR("Nit FFI with Java error: NitObject field not found.\\n");
+ (*env)->ExceptionDescribe(env);
+ exit(1);
+ }
+
+ jlong data = (*env)->GetLongField(env, nit_object, java_field);
+
+ return (void*)data;
+ """
+ ffi_ccu.add_local_function cf
+ end