в моей программе C вызывается из Java, функции C могут вызываться вне контекста Java, но иногда нужны некоторые Java-ресурсы. Я должен объяснить, что такое программа ... Итак, C-библиотека - это плагиновая система, которая может загружать плагины C, плагинам иногда нужен доступ к ресурсам Java, например, для получения идентификатора String.JNI конвертировать String в char *, возвращенный методом экземпляра
Поэтому, когда система плагина загружается, функция инициализации вызывается JNI, поэтому JNIEnv *
и jobject
могут быть сохранены для дальнейшего доступа плагинами.
В классе Java я предоставил метод экземпляра, чтобы получить доступ к этим RESSOURCES, например, у меня есть метод
private String getId() {
return "Bryan";
}
Система С плагин есть функция
char *get_id(char *id) {
jobject jobj = (*jvm.env)->CallObjectMethod(jvm.env, jvm.this, jvm.getId);
jstring jid = jobj;
if (jid == NULL)
debug("get_id", RED "jid NULL");
else
debug("get_id", RED "jid not null"); */
debug("get_id", RED "in get_id, method called");
const char *cid = (*jvm.env)->GetStringUTFChars(jvm.env, jid, NULL);
debug("get_id", RED "converted to c string: %s", cid);
strcpy(id, cid);
debug("get_id", RED "string copied");
(*jvm.env)->ReleaseStringUTFChars(jvm.env, jid, cid);
debug("get_id", RED "string released");
return id;
}
Где JVM представляет собой структуру, содержащие поле env
и obj
, соответствующие JNIEnv *
и jobject
, сохраненные при инициализации, и jvm.getId
, который является methodID
of getId
Метод экземпляра Java, инициализированный одновременно. Отладочный макрос - это всего лишь звонок printf
с flush
, которые помогают мне отлаживать программу.
И это выход после вызова get_id
:
DEBUG IN plugin_system.c LINE 339:
In get_id
in get_id, calling method...
DEBUG IN plugin_system.c LINE 343:
In get_id
jid NULL
DEBUG IN plugin_system.c LINE 346:
In get_id
in get_id, method called
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fb6bcb6cd70, pid=25254, tid=0x00007fb6974be700
#
# JRE version: OpenJDK Runtime Environment (8.0_92-b14) (build 1.8.0_92-b14)
# Java VM: OpenJDK 64-Bit Server VM (25.92-b14 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V [libjvm.so+0x675d70]
#
# Core dump written. Default location: /home/kowa/code/reseaux/projet/ringo/java/bin/core or core.25254
#
# An error report file with more information is saved as:
# /home/kowa/code/reseaux/projet/ringo/java/bin/hs_err_pid25254.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
[4] 25254 abort (core dumped) java Jring Nick 9999 8888 1
Как вы можете видеть вызов Java getId
есть (внешний вид) преуспевающий, но дамп запускается GetStringUTFChars
.
Что случилось?
Каков ваш объект 'jvm'? Структура? Класс? Как вы его заполняете? В общем случае вы не можете кэшировать значения, такие как значение JVM 'env'. Также вы не можете кэшировать объекты или идентификаторы методов, если вы не создадите [глобальную ссылку] (http://stackoverflow.com/questions/112603/what-is-jni-global-reference). –
Это 'struct jvm {JNIEnv * env; jobject this; jclass thisClass; methodID getId; }; ', поле заполняется после загрузки библиотеки после вызова java для собственной функции init. –
Прежде всего, какой набор символов и кодирование вы используете для строк C, системного или определенного? –