Java C附加到现有jvm
我需要从C代码中调用一些Java函数。我找到了一些关于如何从C创建新jvm的教程,但我需要一个现有的jvm(我知道她的PID)。此外,在我的例子中,Java使用JNI调用了C dll,我需要从C回调该JVM 下面是我的部分代码: 爪哇: C:Java C附加到现有jvm,java,c,eclipse,jvm,java-native-interface,Java,C,Eclipse,Jvm,Java Native Interface,我需要从C代码中调用一些Java函数。我找到了一些关于如何从C创建新jvm的教程,但我需要一个现有的jvm(我知道她的PID)。此外,在我的例子中,Java使用JNI调用了C dll,我需要从C回调该JVM 下面是我的部分代码: 爪哇: C: 我以前做过类似的事情,可以粘贴一些代码片段(需要进行错误检查): 请注意,调用的方法是obj void callJavaMethod( JNIEnv *env, jobject obj ) { jclass cl; jmethod
我以前做过类似的事情,可以粘贴一些代码片段(需要进行错误检查): 请注意,调用的方法是
obj
void callJavaMethod( JNIEnv *env, jobject obj )
{
jclass cl;
jmethodID id;
jstring js1;
jstring js2;
jobject byteArray;
/* Im looking for byte[] javaMethod( String s1, String s2 ) */
cl = (*env)->GetObjectClass( env, obj );
id = (*env)->GetMethodID( env, cl, "javaMethod", "(Ljava/lang/String;Ljava/lang/String;)[B" );
/* and now it's called */
js1 = (*env)->NewStringUTF(env, "Hello");
js2 = (*env)->NewStringUTF(env, "Java");
byteArray = (*env)->CallObjectMethod( env, obj, js1, js2 );
/* for other return types there are other CallxxxMethod() functions */
...
}
可以找到Java 7的JNI API文档(应该与Java 6完全相同)除非您从Java加载共享库或修改Java代码以利用,否则您不能以跨平台的方式执行此操作。如果您只关心Windows,则可以完成您的目标,或者使用该函数在现有JVM pid上删除一个新线程。不清楚您的要求,因为您显示的代码似乎暗示JVM进程中已经加载了C DLL。无论如何,您可以阅读我同意,在重读之后,请指定您的本机代码是否已经加载到JVM中,或者您是否正在尝试将本机代码“注入”到已经运行的VM中。这就是我所做的。但是JNIEnv是通过调用Java类得到的吗?如果我尝试在其中搜索一些类,我将收到ClassDefNotFoundException。是的,
JNIEnv
是调用您的方法的JVM的环境。您应该能够通过调用(*env)->FindClass(env,name)
来查找类。请注意,name
必须是完全限定的,例如“java/lang/String”
,而不仅仅是“String”
,而不是在C中查找类,然后调用适当的构造函数等,在java中创建一个对象并将其作为jobject
参数传递给jni函数OK可能更容易,刚刚完成,它就可以工作了。但是当我尝试在C++中做同样的事情(改变FindClass的签名,FindMethod……C++),我会收到一个不满意的Link错误检索我的方法。C++中有什么变化吗?谢谢。CreateRemoteThread技巧需要LoadLibrary地址作为入口点。你不会真的以一个新的线程结束。
#include "hellojni_actions_HelloJNI.h"
void invoke_class(JNIEnv* env) {
// HERE I NEED TO CALL A METHOD OF JAVA CLASS WHICH LOADED ME (HelloJNI.java) IN THE SAME JVM
}
JNIEXPORT jstring JNICALL Java_hellojni_actions_HelloJNI_getHello
(JNIEnv *env, jobject thisObj, jint jvmProcessId){
invoke_class(env);
return (*env)->NewStringUTF(env, "Testing...");
}
void callJavaMethod( JNIEnv *env, jobject obj )
{
jclass cl;
jmethodID id;
jstring js1;
jstring js2;
jobject byteArray;
/* Im looking for byte[] javaMethod( String s1, String s2 ) */
cl = (*env)->GetObjectClass( env, obj );
id = (*env)->GetMethodID( env, cl, "javaMethod", "(Ljava/lang/String;Ljava/lang/String;)[B" );
/* and now it's called */
js1 = (*env)->NewStringUTF(env, "Hello");
js2 = (*env)->NewStringUTF(env, "Java");
byteArray = (*env)->CallObjectMethod( env, obj, js1, js2 );
/* for other return types there are other CallxxxMethod() functions */
...
}