Bonjour,
Mon but est d'ouvrir une fenêtre JNI dans un programme existant. Pour cela j'utilise Cocoa sur Mac. Mon programme C++ ainsi que mes classes java fonctionnent très bien hors du programme global.
Mon soucis est que j'obtiens l'erreur suivante "nextEventMatchingMask should only be called from the Main Thread!" sur la ligne utilisant la fonction objc_msgSend() quand j'insère l'appelle la création de la fenêtre dans le programme global.
voici mon code d'appelle à la fenêtre (la partie du main() est inséré dans une fonction du programme global) :
J'aimerai savoir s'il existe une solution pour faire passer le thread courant pour le thread principale, ou alors une façon détournée d'atteindre mon but.
Merci par avances pour vos réponses.
Mon but est d'ouvrir une fenêtre JNI dans un programme existant. Pour cela j'utilise Cocoa sur Mac. Mon programme C++ ainsi que mes classes java fonctionnent très bien hors du programme global.
Mon soucis est que j'obtiens l'erreur suivante "nextEventMatchingMask should only be called from the Main Thread!" sur la ligne utilisant la fonction objc_msgSend() quand j'insère l'appelle la création de la fenêtre dans le programme global.
voici mon code d'appelle à la fenêtre (la partie du main() est inséré dans une fonction du programme global) :
Bloc de code:
#include <iostream>
#include <jni.h>
#include <objc/objc-runtime.h>
void runCocoaMain(void)
{
id clazz = (id) objc_getClass("NSApplication");
id _Nullable app = objc_msgSend(clazz, sel_registerName("sharedApplication"));
objc_msgSend(app, sel_registerName("run"));
}
int main()
{
using namespace std;
cout<<"arret ..."<<endl;
int i;
cin >> i;
JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine)
JNIEnv *env; // Pointer to native interface
//==================== prepare loading of Java VM ============================
JavaVMInitArgs vm_args; // Initialization arguments
JavaVMOption* options = new JavaVMOption[1]; // JVM invocation options
options[0].optionString = "-Djava.class.path=."; // where to find java .class
vm_args.version = JNI_VERSION_1_8; // minimum Java version
vm_args.nOptions = 1; // number of options
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE; // invalid options make the JVM init fail
//================= load and initialize Java VM and JNI interface ===============
jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !!
delete options; // we then no longer need the initialisation options.
//========================= analyse errors if any ==============================
// if process interuped before error is returned, it's because jvm.dll can't be
// found, i.e. its directory is not in the PATH.
if (rc == JNI_ERR) {
printf("All done, bye bye!\n");
}
if(rc != JNI_OK) {
if(rc == JNI_EVERSION)
cerr << "FATAL ERROR: JVM is oudated and doesn't meet requirements" << endl;
else if(rc == JNI_ENOMEM)
cerr << "FATAL ERROR: not enough memory for JVM" << endl;
else if(rc == JNI_EINVAL)
cerr << "FATAL ERROR: invalid ragument for launching JVM" << endl;
else if(rc == JNI_EEXIST)
cerr << "FATAL ERROR: the process can only launch one JVM an not more" << endl;
else
cerr << "FATAL ERROR: could not create the JVM instance (error code " << rc << ")" << endl;
cin.get();
exit(EXIT_FAILURE);
}
cout << "JVM load succeeded. \nVersion ";
jint ver = env->GetVersion();
cout << ((ver >> 16) & 0x0f) << "." << (ver & 0x0f) << endl;
// First call to JAVA ==================================================================
jclass cls2 = env->FindClass("MyTest2"); // try to find the class
if(cls2 == nullptr) {
cerr << "ERROR: class not found !";
}
else { // if class found, continue
cout << "Class MyTest found" << endl;
// runCocoaMain();
jmethodID mid = env->GetStaticMethodID(cls2, "run", "()V"); // find method
if(mid == nullptr)
cerr << "ERROR: method void mymain() not found !" << endl;
else {
cout << "===Call to java==================" << endl;
env->CallStaticVoidMethod(cls2, mid); // call method
runCocoaMain();
cout << "===End of call to java==========="<<endl;
}
}
// End JAVA calls ==================================================================
jvm->DestroyJavaVM();
cout << "Press any key...";
cin.get();
}
J'aimerai savoir s'il existe une solution pour faire passer le thread courant pour le thread principale, ou alors une façon détournée d'atteindre mon but.
Merci par avances pour vos réponses.