Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Вызов java метода из C++ через JNI


Автор: x8m6 16.12.2010, 22:36
Нужно вызвать метод у java- объекта через JNI.
Вопрос 1: Как получить указатель на интерфейс env?
Вопрос 2: Как получить уже созданный в памяти java-объект (именно получить с уже заполненными полями, а не создать новый экземпляр)?


Автор: LSD 17.12.2010, 17:24
Цитата(x8m6 @  16.12.2010,  23:36 Найти цитируемый пост)
Как получить указатель на интерфейс env?

Это будет первый аргумент переданный в этот метод.
Код

JNIEXPORT jbyteArray JNICALL Java_ReadFile_loadFile
  (JNIEnv * env, jobject jobj, jstring name) {
...




Цитата(x8m6 @  16.12.2010,  23:36 Найти цитируемый пост)
Вопрос 2: Как получить уже созданный в памяти java-объект (именно получить с уже заполненными полями, а не создать новый экземпляр)?

Вызвать Java метод который вернет тебе ссылку на этот объект: http://java.sun.com/docs/books/jni/html/fldmeth.html#49095. Или получить ссылку из поля: http://java.sun.com/docs/books/jni/html/fldmeth.html#30289.

Автор: x8m6 17.12.2010, 23:14
Цитата

Это будет первый аргумент переданный в этот метод.

Мне нельзя вызывать нативный код в Java. 


Цитата

Вызвать Java метод который вернет тебе ссылку на этот объект


Код

jobject thd = ...; /* a java.lang.Thread instance */
 jmethodID mid;
 jclass runnableIntf = 
     (*env)->FindClass(env, "java/lang/Runnable");
 if (runnableIntf == NULL) {
     ... /* error handling */
 }
 mid = (*env)->GetMethodID(env, runnableIntf, "run", "()V");
 if (mid == NULL) {
     ... /* error handling */
 }
 (*env)->CallVoidMethod(env, thd, mid);
 ... /* check for possible exceptions */



т.е. получается чтобы вызвать метод у объекта уже нужно иметь ссылку на этот объект - в данном примере thd. Откуда ее взять? Или можно ее занулить, тогда  после вызова метода вернется объект?
И как получить нужный мне экземпляр(c требуемыми значениями полей)? Я так понимаю что никак. Единст. способ - это синглтон.

Автор: LSD 20.12.2010, 12:09
Цитата(x8m6 @  18.12.2010,  00:14 Найти цитируемый пост)
Мне нельзя вызывать нативный код в Java.

Тогда я вообще не понимаю, как твой код на C++ должен получить управление.


Цитата(x8m6 @  18.12.2010,  00:14 Найти цитируемый пост)
т.е. получается чтобы вызвать метод у объекта уже нужно иметь ссылку на этот объект - в данном примере thd. Откуда ее взять? Или можно ее занулить, тогда  после вызова метода вернется объект?
И как получить нужный мне экземпляр(c требуемыми значениями полей)? Я так понимаю что никак. Единст. способ - это синглтон.

Это уже вопрос не по JNI, это скорее архитектура. Где и как хранить ссылку, чтобы ее можно было получить из произвольного участка кода.

Автор: x8m6 20.12.2010, 20:47
Цитата

Тогда я вообще не понимаю, как твой код на C++ должен получить управление.

получить ссылку на запущенную JVM, от туда достать как-то env.





Автор: LSD 22.12.2010, 11:44
Цитата(x8m6 @  20.12.2010,  21:47 Найти цитируемый пост)
получить ссылку на запущенную JVM, от туда достать как-то env.

Ты хочешь внедриться в уже запущенную JVM? Ну тогда тебе точно не сюда, с помощью JNI внедрится в другой процесс нельзя. И как это сделать будет зависеть от того какая ОС используется.

А вообще, есть JMX с помощью которого можно из другого процесса получить некие данные из уже запущенной JVM.

Автор: Vitaly333 22.12.2010, 14:00
Цитата

с помощью JNI внедрится в другой процесс нельзя.

А как же вот этот метод из jni.h:
Код

_JNI_IMPORT_OR_EXPORT_ jint JNICALL
JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *);


Автор: LSD 23.12.2010, 13:28
Цитата(Vitaly333 @  22.12.2010,  15:00 Найти цитируемый пост)
А как же вот этот метод из jni.h:

А что такого в этом методе?
http://download.oracle.com/javase/1.4.2/docs/guide/jni/spec/invocation.html
Цитата
JNI_GetCreatedJavaVMs

jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen,
jsize *nVMs);

Returns all Java VMs that have been created. Pointers to VMs are written in the buffer vmBuf in the order they are created. At most bufLen number of entries will be written. The total number of created VMs is returned in *nVMs.

JDK 1.1.2 does not support creating more than one VM in a single process.

То что можно создать JVM из native приложения, не означает, что можно так же просто внедрится в уже запущенную JVM.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)