This is only specific to Windows.
Does JNI provide any API that returns all instance of JavaVM* of the calling process?
Consider the following scenario, a C++ dll is injected into a java.exe process. Now the question is, how can the C++ dll locate the current instance of JavaVM* within the process it's running from?
As far as I know, all JNI invocation API require a JNIEnv object which can only be acquired from JavaVM* right? http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html
The traditional way of getting JavaVM* is via JNI_OnLoad but since I'm not writing a native library to be consumed by Java, I don't think that would do the trick. http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/invocation.html
解决方案
jsize nVMs;
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
This code is the "safe" version that asks how big the buffer has to be and then calls a second time to get the data. However, the major Windows JVM (Hotspot) doesn't support more than one JVM per process, so it may be sufficient for you to just allocate a buffer for one element. JNI_GetCreatedJavaVMs is a part of the invocation API and therefore exported by the jvm.dll.
I'm not writing a native library to be consumed by Java
If you are creating the JVM in your library, that's all you need because you have to load the jvm.dll anyways. I can't really help you much because you're not writing how exactly your library is going to be invoked. If your library is used by another native library that either creates the JVM or is loaded from the JVM and it doesn't pass the JavaVM* to you for whatever reason, you could try something like this:
#include
#include
// ...
typedef jint (JNICALL * GetCreatedJavaVMs)(JavaVM**, jsize, jsize*);
GetCreatedJavaVMs jni_GetCreatedJavaVMs;
// ...
jni_GetCreatedJavaVMs = (GetCreatedJavaVMs)GetProcAddress(GetModuleHandle(
TEXT("jvm.dll")), "JNI_GetCreatedJavaVMs");