С приложением к существующему jvm

1

Мне нужно вызвать некоторые функции 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...");

}
  • 1
    Неясно, о чем вы спрашиваете, так как код, который вы показываете, подразумевает, что C DLL уже загружена в процесс JVM. В любом случае, вы можете прочитать stackoverflow.com/questions/22441878/…
  • 0
    Я согласен, после повторного чтения укажите, если ваш родной код уже загружен в JVM или вы пытаетесь «внедрить» нативный код в уже работающую виртуальную машину.
Теги:
jni
jvm

2 ответа

1
Лучший ответ

Я сделал что-то подобное раньше и могу вставить фрагменты кода (проверка ошибок должна быть выполнена):

Обратите внимание, что вызванный метод является объектным методом 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)

  • 0
    Это то, что я сделал. Но JNIEnv - это тот, который вы получаете от вызова Java-класса? Если я попытаюсь найти в нем некоторые классы, я получу исключение ClassDefNotFoundException.
  • 1
    Да, JNIEnv - это среда JVM, из которой вызван ваш компьютер. Вы должны быть в состоянии найти классы, вызывая (*env)->FindClass( env, name ) . Обратите внимание, что name должно быть полностью определено, например, "java/lang/String" , а не просто "String"
Показать ещё 3 комментария
0

Вы не можете сделать это на кросс-платформенном пути, если не выполняете загрузку разделяемой библиотеки с Java или не изменяете свой Java-код, чтобы использовать какой- то IPC. Если вы заботитесь только о Windows, вы можете аб использовать SetWindowsHookEx для достижения своей цели или использовать CreateRemoteThread функцию, чтобы получить новую нить на существующей виртуальной машины Java ВЗОМТ.

  • 0
    Трюк CreateRemoteThread хочет, чтобы адрес LoadLibrary был точкой входа. Вы действительно не заканчиваете с новым потоком.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню