Мне нужно вызвать некоторые функции Java из кода C. Я нашел некоторое руководство по созданию нового jvm из C, но мне нужен существующий jvm (я знаю ее PID). Кроме того, в моем случае, C dll был вызван Java с использованием JNI, мне нужно вызвать обратно JVM из C.
Вот часть моего кода:
ЯВА:
public class HelloJNI {
static {
// hello.dll on Windows or libhello.so on Linux
System.loadLibrary("hello");
}
// native method for call C dll
private native String getHello(int jvmProcessId);
public String doHello(){
return getHello(myProcessId);
}
}
C:
#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...");
}
Я сделал что-то подобное раньше и могу вставить фрагменты кода (проверка ошибок должна быть выполнена):
Обратите внимание, что вызванный метод является объектным методом 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 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 */
...
}
Документацию JNI API для Java 7 можно найти здесь (она должна быть одинаковой для Java 6)
JNIEnv
- это среда JVM, из которой вызван ваш компьютер. Вы должны быть в состоянии найти классы, вызывая (*env)->FindClass( env, name )
. Обратите внимание, что name
должно быть полностью определено, например, "java/lang/String"
, а не просто "String"
Вы не можете сделать это на кросс-платформенном пути, если не выполняете загрузку разделяемой библиотеки с Java или не изменяете свой Java-код, чтобы использовать какой- то IPC. Если вы заботитесь только о Windows, вы можете аб использовать SetWindowsHookEx для достижения своей цели или использовать CreateRemoteThread функцию, чтобы получить новую нить на существующей виртуальной машины Java ВЗОМТ.