Können Sie eine neue JVM in einer C ++ - Funktion erstellen, die mit JNI von Java aus aufgerufen wird?
Also mein Setup ist, dass ich eine .dll habe, die von mir entwickelt wurde A.dll) die in der ursprünglichen Anwendung von einem externen Prozess aufgerufen wird, der im Grunde nur eine EXE-Datei ist, für die ich nicht den Quellcode habe B.exe). Der Zweck von A.dll soll mit einer .jar-Datei kommunizieren, die ebenfalls von mir entwickelt wird C.jar). Also in der Anwendung, die "Kommunikationsflüsse" wie unten gezeigt
B.exe -> A.dll -> (über JNI) -> C.jar
Now, was ich tun möchte, ist, die Anrufe hinzuzufügen, die zwischen @ geh A.dll und C.jar als Teil meiner Testsuite in der Entwicklungsumgebung für C.jar. Was ich bisher habe, ist, dass ich eine andere DLL erstellt habe D.dll) das alle Funktionen in @ spiege A.dll, aber mit JNIEXPORT, und ruft einfach die jeweilige Funktion in @ direkt a A.dll. Der "Kommunikationsfluss" in dieser Situation sieht also folgendermaßen aus:
Einheitentest im C.jar-Entwicklungsframework -> (über JNI) -> D.dll -> A.dll -> (über JNI) -> C.jar
An diesem Punkt ein sehr einfacher Funktionsaufruf, der einfach etwas in @ ausgib C.jar wirkt sich auf die gesamte Kette aus; den ganzen Weg vom Unit-Test-Aufruf und in C.jar. Das Problem entsteht jedoch, wenn ich die Funktion in @ aufruf A.dll erstellt eine neue JVM mitCreateJavaVM (), was den folgenden Fehler erzeugt:
ei der Initialisierung der VM ist ein Fehler aufgetreten. Native Bibliothek konnte nicht geladen werden: Die angegebene Prozedur wurde nicht gefunden.
So im Grunde frage ich mich, ob es tatsächlich möglich ist, dies zu tun, oder ist es einfach unmöglich, @ anzurufCreateJavaVM () wenn es im selben Prozess bereits eine laufende JVM gibt? Ich weiß, dass du nicht anrufen kannstCreateJavaVM () mehrmals innerhalb desselben Prozesses, aber in diesem Fall wird es nur einmal aufgerufen, aber es ist bereits eine JVM im Prozess vorhanden. Können sogar mehrere JVMs im selben Prozess ausgeführt werden?
LÖSUNG
Danke an @ Apangin die Antwort das Code-Snippet unten mein Problem gelöst:
jsize nVMs = 0;
JavaVM** buffer;
jni_GetCreatedJavaVMs = (GetCreatedJavaVMs) GetProcAddress(GetModuleHandle(
TEXT("jvm.dll")), "JNI_GetCreatedJavaVMs");
if (jni_GetCreatedJavaVMs == NULL) {
// stuff
CreateJavaVM(&jvm, (void **) &env, &args);
} else {
jni_GetCreatedJavaVMs(NULL, 0, &nVMs); // 1. just get the required array length
JavaVM** buffer = new JavaVM*[nVMs];
jni_GetCreatedJavaVMs(buffer, nVMs, &nVMs); // 2. get the data
buffer[0]->GetEnv((void **) &env, jni_version); // 3. get environment
jvm = buffer[0];
}