这只针对Windows。
JNI是否提供了返callback用进程的所有JavaVM*
实例的API?
考虑下面的情况,一个C ++ DLL被注入到一个java.exe
进程中。 现在的问题是,C ++ dll如何在正在运行的进程中findJavaVM*
的当前实例?
据我所知,所有的JNI调用API都需要一个JNIEnv
对象,它只能从JavaVM*
获得JavaVM*
对吗? http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html
获得JavaVM*
的传统方法是通过JNI_OnLoad
但是由于我没有编写一个本地库供Java使用,我不认为这样做会有效果。 http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/invocation.html
你可以使用JNI_GetCreatedJavaVMs
:
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
此代码是“安全”版本,询问缓冲区有多大,然后再次调用以获取数据。 但是,主要的Windows JVM(Hotspot)不支持每个进程多于一个JVM,所以仅仅为一个元素分配一个缓冲区就足够了。 JNI_GetCreatedJavaVMs
是调用API的一部分,因此由jvm.dll
导出。
我不写一个本地库供Java使用
如果你正在库中创建JVM,那么这就是你所需要的,因为你必须加载jvm.dll
。 我不能真正帮助你,因为你没有写出你的库的调用方式。 如果你的库被另外一个本地库使用,它创建了JVM或者从JVM加载,并且由于某种原因它不会传递JavaVM*
给你,你可以尝试如下所示:
#include <Windows.h> #include <jni.h> // ... typedef jint (JNICALL * GetCreatedJavaVMs)(JavaVM**, jsize, jsize*); GetCreatedJavaVMs jni_GetCreatedJavaVMs; // ... jni_GetCreatedJavaVMs = (GetCreatedJavaVMs)GetProcAddress(GetmoduleeHandle( TEXT("jvm.dll")), "JNI_GetCreatedJavaVMs");