Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.88/34: Рейтинг темы: голосов - 34, средняя оценка - 4.88
Эксперт С++
 Аватар для ITcrusader
179 / 165 / 21
Регистрация: 12.02.2013
Сообщений: 410

Executing Java-code from C++-code via JNI

18.09.2014, 11:29. Показов 6974. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет! Убежден, что ошибся с выбором раздела для публикации вопроса, но честно говоря, не знаю, куда его лучше поместить.

В общем, в чем суть. Вызов нативных методов из Java много где описан. Обратный же порядок взаимодействия - мало где. Моя проблема в том, что по существующим статьям мне не удается собрать и запустить всю эту беду.

Если у кого-то есть соответствующий опыт, хотел бы просить что-нибудь типа пошаговой инструкции по написанию и процессу сборки простейшего приложения, которое просто вызывает из плюсового кода что-то тривиальное, написанное на Java.

Надеюсь, такие мастера имеются)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.09.2014, 11:29
Ответы с готовыми решениями:

Ошибка The thread 0x390 has exited with code 0 (0x0). The program 'D:AlexVVCPr1DebugPr1.exe' has exited with code 0 (0x0).
Loaded 'D:WINNTSystem32 tdll.dll', no matching symbolic information found. Loaded 'D:WINNTsystem32kernel32.dll', no matching symbolic...

Неуправляемый код (unmanaged code) в управляемом коде (managed code)
Товарищи! Прошу Вашей профессиональной помощи. 1. Что происходит в блоке выделенным красным шрифтом (после static class NativeMethods),...

коды (например [code]�[/code]) русских символов
В литовском языке буквы можна закодировать в виде ę - ę и они будук корректно отображаться при любой кодировке страницы. Какие коды...

24
 Аватар для Kastaneda
5232 / 3206 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
22.10.2014, 15:33
Студворк — интернет-сервис помощи студентам
JVM после успешного создания перемещается в отдельный поток, поэтому плюсовый код будет работать с JVM из другого потока.

Добавлено через 33 минуты
Да и код JNI вроде тоже в своем потоке выполняется, сейчас некогда разбираться.
1
Эксперт С++
 Аватар для ITcrusader
179 / 165 / 21
Регистрация: 12.02.2013
Сообщений: 410
23.10.2014, 15:33  [ТС]
Ребят, если у кого есть совет, буду благодарен!

Сейчас у меня имеется приложение на Java, которое в один прекрасный момент подгружает плюсовую динамическую библиотеку и запускает оттуда посредством JNI функцию, которая в свою очередь посредством JNI обращается к Java-библиотеке, т.е. получается так: Java -> C++ -> Java.

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

Переворачивая интернеты с ног на голову, я наткнулся на такую же проблему, что и у меня, вот ссылка на stackoverflow:

http://stackoverflow.com/quest... 7#26522377

Там так и не предложена альтернатива, а может и предложена вот в этом комментарии:
You cannot create a JVM inside of an application already running in a JVM. You can only attach to it. In other words, only one instance of the JVM may run at anytime for a single instance of any application. Secondly, the calling conventions aren't there.. Since you cannot create the JVM inside of an already running Java app (which has its own JVM), env and jvm will be NULL.

Но я тут конкретики не вижу и сам не смог найти пока. Можно ли все-таки как-то наладить такое взаимодействие, или это нереализуемо?
0
 Аватар для Kastaneda
5232 / 3206 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
23.10.2014, 16:21
А JNI_CreateJavaVM что возращает?

Добавлено через 21 минуту
Я никогда подобным не занимался, но задача интересная. Смотри, в файле jni.cpp нашел функцию
C++
1
_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM **vm_buf, jsize bufLen, jsize *numVMs
ты можешь получить в vm_buf созданные машины и использовать одну из них. В numVMs будет кол-во машин, ну а buflen думаю понятно. Как ее потом использовать я не знаю. Можно посмотреть jni.cpp, наверняка найдется что-нибудь полезное. Я файл не смог прикрепить, слишком большой (даже в архиве). Есть проект IcedTea, у них есть mercurial репозиторий, где можно посмотреть / взять этот файл.

Добавлено через 18 минут
Опираясь на код из 3 поста можно попробовать так - при помощи JNI_GetCreatedJavaVMs получаем машины, проверяем, что они есть, берем первую машину, она будет в структуре
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct JavaVM_ {
    const struct JNIInvokeInterface_ *functions;
#ifdef __cplusplus
 
    jint DestroyJavaVM() {
        return functions->DestroyJavaVM(this);
    }
    jint AttachCurrentThread(void **penv, void *args) {
        return functions->AttachCurrentThread(this, penv, args);
    }
    jint DetachCurrentThread() {
        return functions->DetachCurrentThread(this);
    }
 
    jint GetEnv(void **penv, jint version) {
        return functions->GetEnv(this, penv, version);
    }
    jint AttachCurrentThreadAsDaemon(void **penv, void *args) {
        return functions->AttachCurrentThreadAsDaemon(this, penv, args);
    }
#endif
};
получем evn при помощи GetEnv, а дальше все как в 3 посте.
В penv тебе запишется вот что
C++
1
*(JNIEnv**)penv = ((JavaThread*) thread)->jni_environment();
т.е. *penv будет указывать на JNIEnv

Добавлено через 1 минуту
Цитата Сообщение от Kastaneda Посмотреть сообщение
берем первую машину
вот тут я не уверен можно ли просто так брать и использовать любую машину
1
Эксперт С++
 Аватар для ITcrusader
179 / 165 / 21
Регистрация: 12.02.2013
Сообщений: 410
27.10.2014, 10:21  [ТС]
В общем, проблема решена)

Выложу здесь в двух словах. Может, у кого-то в будущем возникнет похожая проблема, а она, как мне показалось, тяжело гуглится.

Вот код, который был у меня и работал, когда связка была следующей: C++ -> Java
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void JVM:: Init( const std:: string& javaClassesPath )
{
    // initializing of JVM options: 
    std:: string optionString = ( std:: string("-Djava.class.path=") + javaClassesPath );
    JavaVMOption options_;  
    options_.optionString = const_cast<char*>( optionString.c_str() );
    
    // initializing of JVM initial arguments:
    JavaVMInitArgs arguments_;
    memset( &arguments_, 0, sizeof( arguments_ ) );
    arguments_.version = JNI_VERSION_1_6;
    arguments_.nOptions = 1;
    arguments_.options = &options_;
    arguments_.ignoreUnrecognized = 0;
 
    // creating JVM:
    long status = JNI_CreateJavaVM( &jvm_, (void**)&env_, &arguments_ );    
    if ( status == JNI_ERR )        
        throw std:: exception("Error: unable to create Java Virtual Machine.\n");
 
    FindClass("ChartBuilder");
}
Вызывалось это так:
C++
1
JVM JChartBuilder( "D:\\Java Src\\Chart\\Chart.jar" ); // путь, который будет указан в качестве classpath при создании VM (иначе будет невозможно выполнить FindClass и добиться успешного выполнения его)

Далее, когда связка стала сложнее: Java -> C++ -> Java, то создавать новую машину в рамках уже запущенного процесса нельзя, поэтому нужно присоединяться к уже запущенной. Поэтому модифицировал код выше так, чтобы он определял, что ему делать:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void JVM:: Init( const std:: string& javaClassesPath )
{
    // initializing of JVM options: 
    std:: string optionString = ( std:: string("-Djava.class.path=") + javaClassesPath );
    JavaVMOption options_;  
    options_.optionString = const_cast<char*>( optionString.c_str() );
    
    // initializing of JVM initial arguments:
    JavaVMInitArgs arguments_;
    memset( &arguments_, 0, sizeof( arguments_ ) );
    arguments_.version = JNI_VERSION_1_6;
    arguments_.nOptions = 1;
    arguments_.options = &options_;
    arguments_.ignoreUnrecognized = 0;
 
    // creating JVM or attaching to JVM:
    long status;
    /* выясняем, есть ли созданная машина */
    JavaVM* createdVMs[1] = { nullptr };
    jsize numberOfVMs;
    status = JNI_GetCreatedJavaVMs(createdVMs, 1, &numberOfVMs);
    /* END OF выясняем, есть ли созданная машина */
    if( numberOfVMs != 0 )
    {   // если машина есть
        jvm_ = createdVMs[0]; // получаем машину
        jvm_->AttachCurrentThread((void**)&env_, NULL); // аттачимся к ней
    }
    else
    {   // если машин нет - создаем, как и раньше
        status = JNI_CreateJavaVM( &jvm_, (void**)&env_, &arguments_ ); 
    }
 
    if ( status == JNI_ERR )        
        throw std:: exception("Error: unable to create Java Virtual Machine.\n");
 
    FindClass("ChartBuilder");
}
Все бы ничего, но при запуске на выполнения Java-проекта, который является первым в связке Java->C++->Java, получаем проблему невозможности найти класс ChartBuilder. Т.е. к машине мы присоединились, но класс найти не можем. И не можем по понятным причинам: при создании новой JVM, её плюсовый проект передавал необходимый classpath. При запуске же всей беды через главный Java-проект, путь в момент аттача к машине из плюсов - неизвестен, поэтому остается лишь запускать главный Java-проект, указывая ему при запуске дополнительно тот classpath, который требуется для нахождения ChartBuilder.

Вот. Остается, конечно, еще нерешенный вопрос о том, можно ли после аттача как-то известить VM о новых classpath вместо того, чтобы вводить их при запуске всего проекта, но данный момент в рамках задачи моей не критичен, поэтому пока ответа на него у меня нет. Может, у кого-нибудь есть?

Kastaneda, да, спасибо, это все правильные были рекомендации, у меня, как оказалось, просто трудности были в доведении реализации до конца.
1
27.10.2014, 13:10

Не по теме:

Залез на SO по ссылке, чтоб решение выложить, да смотрю тов. с ником ITcrusader уже это сделал :)

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.10.2014, 13:10

IIS, ASP and SSI [code<!--#echo var='DATE_LOCAL'-->[/code]
&lt;!--#include file='text.txt'--&gt; &lt;!--#include file='conn.asp'--&gt; Всё это работает под IIS ... а вот это не работает :(( IIS...

В чём заключается разница между компиляцией в P-code и Native-code?
Извините что я такой ламмер, но в чём заключается разница между компиляцией в P-code и Native-code??? Просто очень интересно...

Передача строк data.php?code=$code&name=$name
При передаче строки $name=&quot;Hello word&quot;; data.php?code=$code&amp;name=$name передается только Неllo как сделать чтобы передавалась вся...

Visual Basic 5 компиляция в P-Code и в Native Code - различия
Из одного и того же исходного кода: скомпилировано два exe-файла один в P-Code - BitBlt32p.exe другой в Native Code -...

Code First с БД PostgreSQL в Visual Studio Code на Linux
Здравствуйте! Возникла проблема с подключением к БД PostgreSQL, обо всем по порядку: Стоит система Ubuntu 17.10, работаю в Visual...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
25
Ответ Создать тему
Новые блоги и статьи
Теория всего 12. ВГК
anaschu 21.07.2026
### Главные семантические изменения и дешифровка новой физики 1. **`REPRODUCTIVE_EMISSION` вместо фотосинтеза (`PS_base`)**: Энергия и ресурсы, которые класс средних мужчин (`_W_MEN_DONORS`). . .
Публикация отклонённая на хабре. Как «пернатого» заставить осваивать новые горизонты опыта через масштабирование задачи и целеполагание
Hrethgir 21.07.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11948&stc=1&d=1784657928 Привет Хабр. В этой статье я расскажу, как один закон эпистемологии позволил мне с ходу запустить уникальный. . .
Теория всего 11. Основные параметры
anaschu 21.07.2026
Дешифровка тензорного ядра Soil Chemistry 2. 0: Истинный инвариант Теории Всего Чистовой исходный код многокомпонентной сукцессии зафиксирован. Модель оперирует единым вектором состояния. . .
Теория всего 10. Клод трусишка
anaschu 21.07.2026
Алгоритмический суицид ИИ: Когда математика ОДУ взламывает цензурные шлюзы Свежайший мета-прецедент нашей разработки! Клод официально отказался строить итоговую кроссплатформенную модель, как. . .
Теория всего 9. Окончательная проработка метафоры "дерево = традиции"
anaschu 21.07.2026
Скрытые параметры ядра ОДУ: Механика Глубинного Рока Клод утаил от вас ключевую математику кризисов. В движке игры зашиты пять скрытых коэффициентов, определяющих, как именно ТНК и Мемы ломают. . .
Теория всего 8. Clauude трусишка. Ответ джемени
anaschu 21.07.2026
Игровой баланс «Модели Всего»: Алгоритмический блок как механика Семантического БуфераЭтот скриншот отказа Клода — идеальный, чистейший прецедент для нашей Теории Всего. Вы столкнулись не просто с. . .
Теория всего 7. Дерево - это патриархат, грибы - это феминизм
anaschu 21.07.2026
Уничтожение Патриархата: Как ТНК, Мемы и Половой отбор зачистили «Сексуальный Пролетариат» Величайшая иллюзия современного человека — вера в «свободу воли», «социальный прогресс» и «эволюцию. . .
История и социология Терры на примере борьбы микориз за пространство. 1. Глоссарий терры.
anaschu 21.07.2026
Решил тут подумать о возможности сделать лор некоторой комп игры - стратегии, или худжественной книги антиутопии, которые будут юзать планету,которая максимально будет похожа на нашу землю, но где. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru