Невозможно вызвать методы Java из оболочки C++ в JNI.JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Невозможно вызвать методы Java из оболочки C++ в JNI.

Сообщение Anonymous »

Я новичок в JNI и C++. У меня есть некоторый API, которому требуется общий указатель с некоторым обработчиком для подписки на некоторые сообщения. Я могу вызвать требуемый метод в своем обработчике в «основном» методе C++, но когда я вызываю его из оболочки C++, я получаю ошибку JVM и мое приложение аварийно завершает работу. Мой родной метод следующий:

Код: Выделить всё

public native int subscribe(Handler handler);
Класс Java Handler:

Код: Выделить всё

public class Handler {
public void call(String m1, String m2) {
System.out.println("call: " + m1 + " " + m2);
}
Реализация JNI:

Код: Выделить всё

JNIEXPORT jint JNICALL Java_com_lib_NativeClient_subscribe (JNIEnv* env, jobject thisObj, jobject javaHandler) {

jclass handlerClass = env->GetObjectClass(javaHandler);
jmethodID call = env->GetMethodID(handlerClass, "call", "(Ljava/lang/String;Ljava/lang/String;)V");
const std::string &message1 = "message1";
const std::string &message2 = "message2";
jstring javMessage1 = env->NewStringUTF((const char* )message1.c_str());
jstring javMessage2 = env->NewStrbingUTF((const char* )message2.c_str());
env->CallVoidMethod(javaHandler, call, javMessage1, javMessage2);

JavaWrapperHandler javaWrapperHandler = JavaWrapperHandler(env, javaHandler);
std::shared_ptr handlerSharedPointer = std::make_shared(javaWrapperHandler);

return some::lib::subscribe(handlerSharedPointer);
};
Все работает нормально, я вызываю метод «вызов» с помощью этого кода. Но мне нужно вызвать этот метод после того, как я подпишусь на сообщения, т.е. Субъект позвонит ему. Я пишу оболочку C++ для своего Java-класса, чтобы передать ее методу подписки:

Код: Выделить всё

class JavaWrapperHandler : public some::lib::Handler {
JNIEnv* env;
jobject javaHandler;
public:
JavaWrapperHandler(JNIEnv* genEnv, jobject handler) {
env = genEnv;
javaHandler = env->NewGlobalRef(handler);
}

~JavaWrapperHandler() {
env->DeleteGlobalRef(javaHandler);
}

virtual void call(const std::string &message1, const std::string &message2) {
jclass handlerClass = env->GetObjectClass(javaHandler);
jmethodID call = env->GetMethodID(handlerClass, "call", "(Ljava/lang/String;Ljava/lang/String;)V");  // Here I get error
jstring javMessage1 = env->NewStringUTF((const char* )message1.c_str());
jstring javMessage2 = env->NewStringUTF((const char* )message2.c_str());
env->CallVoidMethod(javaHandler, call, javMessage1, javMessage2);

};
};
Когда субъект вызывает метод «вызов», я получаю ошибку JVM:

Java обнаружила фатальную ошибку Среда выполнения:
SIGSEGV (0xb) по адресу pc=0x7694d8a4, pid=5681, tid=5702
Версия JRE: среда выполнения OpenJDK (Zulu11. 31+16-CA) (11.0.3+7) (сборка 11.0.3+7-LTS)
ВМ Java: клиентская виртуальная машина OpenJDK (11.0.3+7-LTS, смешанный режим, последовательный gc, linux- Arm)
Проблемный кадр:
V [libjvm.so+0x3e58a4] get_method_id(JNIEnv_, _jclass, char const*, char const*, bool, Thread*) >>[ clone .isra.149]+0x288

Что не так?

Подробнее здесь: https://stackoverflow.com/questions/630 ... per-in-jni
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»